基于Node.js的WebSocket通信实现


Posted in Javascript onMarch 11, 2017

node的依赖包

node中实现Websocket的依赖包有很多,websocket、ws均可,本文选取ws来实现,首先安装依赖

npm install ws

聊天室实例

假如A,B,C,D用户均通过客户端连接到Websocket服务,其中每个人发的消息都需要将其通过Websocket转发给其他人,此场景类似于服务端将A的消息广播给组内其他用户。

服务端实现

首先来看服务端程序,具体的工作流程分以下几步:

  1. 创建一个WebSocketServer的服务,同时监听8080端口的连接请求。
  2. 每当有新的客户端连接该WebSocket成功时,便将该连接push到连接池的数组中。
  3. 监听message事件,当该事件发生时,遍历连接池,以连接为单位将该消息转发到对应的客户端
  4. 监听close事件,当该事件发生时,将该连接移出连接池

服务端代码

var WebSocketServer = require('ws').Server,
  wss = new WebSocketServer({port: 8080});

// 连接池
var clients = [];

wss.on('connection', function(ws) {
  // 将该连接加入连接池
  clients.push(ws);
  ws.on('message', function(message) {
    // 广播消息
    clients.forEach(function(ws1){
      if(ws1 !== ws) {
        ws1.send(message);
      }
    })
  });

  ws.on('close', function(message) {
    // 连接关闭时,将其移出连接池
    clients = clients.filter(function(ws1){
      return ws1 !== ws
    })
  });
});

客户端实现

<html>
<input type="text" id="text">
<input type="button" onclick="sendMessage()" value="online">
<script>
  var ws = new WebSocket("ws://localhost:8080");

  ws.onopen = function (e) {
    console.log('Connection to server opened');
  }
  ws.onmessage = function(event) { 
    console.log('Client received a message', event); 
  }; 
  ws.onclose = function (e) {
    console.log('connection closed.');
  }
  function sendMessage() {
      ws.send(document.getElementById('text').value);
  }
</script>
</html>

如何发现用户?

通过上述的demo可以看到,WebSocket都是基于连接的,也就是说我们知道data是从那个connection发过来,但并不知道使用客户端的是李雷或者韩梅梅,这可如何是好?再想另一种场景,李雷只想给韩梅梅发消息,不想将消息广播给其他客户端,此时我们就需要在Server端能够标识用户身份和连接的对应关系。

于是,需要在客户端连接到WebSocket之后,紧接着再发一次请求,告诉Server我的user_id是多少,Server将此user_id与connection之间的关系存储在hashmap中,至此就建立了user_id与connection的对应关系。当需要发送消息给对应的客户端,从此hashmap中取出对应用户的connection信息,调用其send方法发出消息即可。

依赖包

npm install hashmap

服务端实现

var WebSocketServer = require('ws').Server, webSocketServer = new WebSocketServer({port: 8080});
var HashMap = require('hashmap');

// record the client
var userConnectionMap = new HashMap();
var connectNum = 0;

// connection
webSocketServer.on('connection', function(ws) {
  ++ connectNum;
  console.log('A client has connected. current connect num is : ' + connectNum);
  ws.on('message', function(message) {
    var objMessage = JSON.parse(message);
    var strType = objMessage['type'];

    switch(strType) {
      case 'online' : 
        userConnectionMap.set(objMessage['from'], ws);
        break;
      default:
        var targetConnection = userConnectionMap.get(objMessage['to']);
        if (targetConnection) {
          targetConnection.send(message);
        }
    }
  });

  ws.on('close', function(message) {
    var objMessage = JSON.parse(message);
    userConnectionMap.remove(objMessage['from']);
  });
});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js获取div高度的代码
Aug 09 Javascript
javascript 强制刷新页面的实现代码
Dec 13 Javascript
js 获取Listbox选择的值的代码
Apr 15 Javascript
IFrame跨域高度自适应实现代码
Aug 16 Javascript
使用js获取图片原始尺寸
Dec 03 Javascript
JS深度拷贝Object Array实例分析
Mar 31 Javascript
js实现简单的碰壁反弹效果
Aug 30 Javascript
React项目动态设置title标题的方法示例
Sep 26 Javascript
javascript 对象 与 prototype 原型用法实例分析
Nov 11 Javascript
详解如何在Javascript和Sass之间共享变量
Nov 13 Javascript
实例分析JS中的相等性判断===、 ==和Object.is()
Nov 17 Javascript
解决vue addRoutes不生效问题
Aug 04 Javascript
js原生Ajax的封装和原理详解
Mar 11 #Javascript
ThinkPHP+jquery实现“加载更多”功能代码
Mar 11 #Javascript
Bootstrap的Carousel配合dropload.js实现移动端滑动切换图片
Mar 10 #Javascript
基于Bootstrap框架实现图片切换
Mar 10 #Javascript
angularjs ui-router中路由的二级嵌套
Mar 10 #Javascript
AngularJS ui-router (嵌套路由)实例
Mar 10 #Javascript
微信小程序手势操作之单触摸点与多触摸点
Mar 10 #Javascript
You might like
如何在PHP中使用Oracle数据库(5)
2006/10/09 PHP
学习php设计模式 php实现访问者模式(Visitor)
2015/12/07 PHP
Yii针对添加行的增删改查操作示例
2016/10/18 PHP
PHP连接sftp并下载文件的方法教程
2018/08/26 PHP
基于JQuery的简单实现折叠菜单代码
2010/09/15 Javascript
jquery中实现简单的tabs插件功能的代码
2011/03/02 Javascript
jQuery EasyUI API 中文文档 - Parser 解析器
2011/09/29 Javascript
js中有关IE版本检测
2012/01/04 Javascript
原生js实现跨浏览器获取鼠标按键的值
2013/04/08 Javascript
获取offsetTop和offsetLeft值的js代码(兼容)
2013/04/16 Javascript
node.js使用nodemailer发送邮件实例
2014/03/10 Javascript
jquery动态更换设置背景图的方法
2014/03/25 Javascript
JavaScript实现16进制颜色值转RGB的方法
2015/02/09 Javascript
JavaScript操作选择对象的简单实例
2016/05/16 Javascript
JavaScript动态添加css样式和script标签
2016/07/19 Javascript
Vue.js render方法使用详解
2017/04/05 Javascript
原生JS实现的碰撞检测功能示例
2018/05/18 Javascript
jQuery实现动画、消失、显现、渐出、渐入效果示例
2018/09/06 jQuery
在vue中使用express-mock搭建mock服务的方法
2018/11/07 Javascript
jQuery AJAX与jQuery事件的分析讲解
2019/02/18 jQuery
《javascript设计模式》学习笔记四:Javascript面向对象程序设计链式调用实例分析
2020/04/07 Javascript
[48:22]VGJ.S vs VG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python中的__new__与__init__魔术方法理解笔记
2014/11/08 Python
常见python正则用法的简单实例
2016/06/21 Python
Python判断字符串是否为字母或者数字(浮点数)的多种方法
2018/08/03 Python
Django框架使用内置方法实现登录功能详解
2019/06/12 Python
Python实现病毒仿真器的方法示例(附demo)
2020/02/19 Python
美国浴缸、水槽和水龙头购物网站:Vintage Tub & Bath
2019/11/05 全球购物
开业庆典邀请函
2014/01/08 职场文书
幼儿园教师奖惩制度
2014/02/01 职场文书
城管综合整治方案
2014/05/01 职场文书
党员个人对照检查材料
2014/10/01 职场文书
2015新年寄语大全
2014/12/08 职场文书
Django 实现jwt认证的示例
2021/04/30 Python
如何利用pygame实现打飞机小游戏
2021/05/30 Python
动视暴雪取消疫苗禁令 让所有员工返回线下工作
2022/04/03 其他游戏