基于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 相关文章推荐
JQuery onload、ready概念介绍及使用方法
Apr 27 Javascript
angular简介和其特点介绍
Jan 29 Javascript
浅谈JavaScript中setInterval和setTimeout的使用问题
Aug 01 Javascript
jQuery幻灯片特效代码分享--鼠标滑过按钮时切换(2)
Nov 18 Javascript
跟我学习javascript的严格模式
Nov 16 Javascript
js弹出框、对话框、提示框、弹窗实现方法总结(推荐)
May 31 Javascript
jQuery实现table中的tr上下移动并保持序号不变的实例代码
Jul 11 Javascript
在JavaScript中调用Java类和接口的方法
Sep 07 Javascript
JavaScript正则表达式实例详解
Oct 16 Javascript
Bootstrap和Java分页实例第二篇
Dec 23 Javascript
微信小程序 二维码canvas绘制实例详解
Jan 06 Javascript
解决vue props传Array/Object类型值,子组件报错的情况
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
PHP数组实例总结与说明
2011/08/23 PHP
php中fsockopen用法实例
2015/01/05 PHP
PHP 使用redis简单示例分享
2015/03/05 PHP
深入解析PHP中foreach语句控制数组循环的用法
2015/11/30 PHP
Laravel 修改验证异常的响应格式实例代码详解
2020/05/25 PHP
新浪中用来显示flash的函数
2007/04/02 Javascript
javascript下判断一个元素是否存在的代码
2010/03/05 Javascript
js 第二代身份证号码的验证机制代码
2011/05/12 Javascript
浅析LigerUi开发中谨慎载入common.css文件
2013/07/09 Javascript
JScript分割字符串示例代码
2013/09/04 Javascript
解析Javascript中难以理解的11个问题
2013/12/09 Javascript
什么是MEAN?JavaScript编程中的MEAN是什么意思?
2014/12/18 Javascript
jquery单击事件和双击事件冲突解决方案
2016/03/02 Javascript
AngularJS ng-app 指令实例详解
2016/07/30 Javascript
vue开发心得和技巧分享
2016/10/27 Javascript
jQuery图片轮播实现并封装(一)
2016/12/03 Javascript
JavaScript订单操作小程序完整版
2017/06/23 Javascript
微信小程序项目实践之主页tab选项实现
2018/07/18 Javascript
详解vue-cli3 中跨域解决方案
2019/04/10 Javascript
云服务器部署Node.js项目的方法步骤(小白系列)
2020/03/23 Javascript
python访问类中docstring注释的实现方法
2015/05/04 Python
用python实现的线程池实例代码
2018/01/06 Python
python+matplotlib绘制旋转椭圆实例代码
2018/01/12 Python
python获取时间及时间格式转换问题实例代码详解
2018/12/06 Python
python实现简单日期工具类
2019/04/24 Python
PyQt4实时显示文本内容GUI的示例
2019/06/14 Python
python内置函数sorted()用法深入分析
2019/10/08 Python
HTML5 WebGL 实现民航客机飞行监控系统
2019/07/25 HTML / CSS
美国鲍勃商店:Bob’s Stores
2018/07/22 全球购物
餐饮业的创业计划书范文
2013/12/26 职场文书
党的群众路线剖析材料
2014/10/09 职场文书
保证书格式
2015/01/16 职场文书
介绍信格式
2015/01/30 职场文书
微软Win11什么功能最惊艳? Windows11新功能特性汇总
2021/11/21 数码科技
python数字图像处理实现图像的形变与缩放
2022/06/28 Python
python语言中pandas字符串分割str.split()函数
2022/08/05 Python