基于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 相关文章推荐
Javascript与vbscript数据共享
Jan 09 Javascript
IE/FireFox具备兼容性的拖动代码
Aug 13 Javascript
关于window.pageYOffset和document.documentElement.scrollTop
Apr 05 Javascript
jquery插件如何使用 jQuery操作Cookie插件使用介绍
Dec 15 Javascript
JS读取XML文件数据并以table形式显示数据的方法(兼容IE与火狐)
Jun 02 Javascript
js自调用匿名函数的三种写法(推荐)
Aug 19 Javascript
jQuery插件版本冲突的处理方法分析
Jan 16 Javascript
JavaScript实现带有子菜单和控件的slider轮播图效果
Nov 01 Javascript
axios向后台传递数组作为参数的方法
Aug 11 Javascript
vue多个元素的样式选择器问题
Nov 29 Javascript
纯js+css实现仿移动端淘宝网站的弹出详情框功能
Dec 29 Javascript
Javascript使用integrity属性进行安全验证
Nov 07 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
MySQL授权问题总结
2007/05/06 PHP
IStream与TStream之间的相互转换
2008/08/01 PHP
PHP中使用匿名函数操作数据库的例子
2014/11/17 PHP
PHP简单实现模拟登陆功能示例
2017/09/15 PHP
yii框架结合charjs实现统计30天数据的方法
2020/04/04 PHP
JavaScript版代码高亮
2006/06/26 Javascript
JavaScript 版本自动生成文章摘要
2008/07/23 Javascript
jQuery 行背景颜色的交替显示(隔行变色)实现代码
2009/12/13 Javascript
Fixie.js 自动填充内容的插件
2012/06/28 Javascript
JS的document.all函数使用示例
2013/12/30 Javascript
js实现的标题栏新消息闪烁提示效果
2014/06/06 Javascript
js点击返回跳转到指定页面实现过程
2020/08/20 Javascript
Bootstrap编写导航栏和登陆框
2016/05/30 Javascript
你知道setTimeout是如何运行的吗?
2016/08/16 Javascript
Bootstrap下拉菜单样式
2017/02/07 Javascript
详解vue.js的devtools安装
2017/05/26 Javascript
AngularJS实现的省市二级联动功能示例【可对选项实现增删】
2017/10/26 Javascript
Python删除Java源文件中全部注释的实现方法
2017/08/30 Python
python3爬取数据至mysql的方法
2018/06/26 Python
Python PyInstaller安装和使用教程详解
2020/01/08 Python
Python实现查找数据库最接近的数据
2020/06/08 Python
详解Python中的路径问题
2020/09/02 Python
Pytorch实验常用代码段汇总
2020/11/19 Python
python中altair可视化库实例用法
2021/01/26 Python
html+css3实现的登录界面
2020/12/09 HTML / CSS
HTML5 表单验证失败的提示语问题
2017/07/13 HTML / CSS
在加拿大在线租赁和购买电子游戏:Game Access
2019/09/02 全球购物
医学院学生求职简历的自我评价
2013/10/24 职场文书
可口可乐广告词
2014/03/20 职场文书
房产继承公证书
2014/04/09 职场文书
《大禹治水》教学反思
2014/04/27 职场文书
学生无故旷课检讨书
2014/09/20 职场文书
2014年实习期工作总结
2014/11/27 职场文书
音乐课外活动总结
2015/05/09 职场文书
工厂员工辞职信范文
2015/05/12 职场文书
《草船借箭》教学反思
2016/02/23 职场文书