基于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 相关文章推荐
中文输入法不触发onkeyup事件的解决办法
Jul 09 Javascript
显示今天的日期js代码(阳历和农历)
Sep 30 Javascript
ECMAScript6新增值比较函数Object.is
Jun 12 Javascript
JQuery EasyUI的使用
Feb 24 Javascript
Bootstrap布局组件教程之Bootstrap下拉菜单
Jun 12 Javascript
jQuery使用each方法与for语句遍历数组示例
Jun 16 Javascript
JavaScript实现简单的拖动效果
Jul 02 Javascript
微信小程序之拖拽排序(代码分享)
Jan 21 Javascript
vue购物车插件编写代码
Nov 27 Javascript
js+html5 canvas实现ps钢笔抠图
Apr 28 Javascript
vue+element表格导出为Excel文件
Sep 26 Javascript
javascript解析json格式的数据方法详解
Aug 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数据访问之增删改查操作
2016/05/09 PHP
PHPCrawl爬虫库实现抓取酷狗歌单的方法示例
2017/12/21 PHP
浅谈PHP进程管理
2019/03/08 PHP
php扩展开发入门demo示例
2019/09/23 PHP
几个高效,简洁的字符处理函数
2007/04/12 Javascript
Javascript 错误处理的几种方法
2009/06/13 Javascript
JavaScript 10件让人费解的事情
2010/02/15 Javascript
浅析Javascript使用include/require
2013/11/13 Javascript
javascript实现点击按钮让DIV层弹性移动的方法
2015/02/24 Javascript
AspNet中使用JQuery上传插件Uploadify详解
2015/05/20 Javascript
jQuery实现分章节锚点“回到顶部”动画特效代码
2015/10/23 Javascript
JS+CSS实现的漂亮渐变背景特效代码(6个渐变效果)
2016/03/25 Javascript
浅谈JavaScript中promise的使用
2017/01/11 Javascript
vue-router:嵌套路由的使用方法
2017/02/21 Javascript
jquery实现回车键触发事件(实例讲解)
2017/11/21 jQuery
js实现页面多个日期时间倒计时效果
2019/06/20 Javascript
关于layui 实现点击按钮添加一行(方法渲染创建的table)
2019/09/29 Javascript
Vue实现点击箭头上下移动效果
2020/06/11 Javascript
深入解析Python中的urllib2模块
2015/11/13 Python
python批量添加zabbix Screens的两个脚本分享
2017/01/16 Python
Python爬取网易云音乐上评论火爆的歌曲
2017/01/19 Python
Python实现树莓派WiFi断线自动重连的实例代码
2017/03/16 Python
使用python实现mqtt的发布和订阅
2019/05/05 Python
CSS3实现线性渐变用法示例代码详解
2020/08/07 HTML / CSS
英国音乐设备和乐器商店:Gear4music
2017/10/16 全球购物
澳大利亚波西米亚风连衣裙在线商店:Fortunate One
2019/04/01 全球购物
会计专业毕业生自我评价
2013/09/25 职场文书
销售自荐信
2013/10/22 职场文书
清洁工岗位职责
2014/01/29 职场文书
乔丹名人堂演讲稿
2014/05/24 职场文书
制冷与空调专业毕业生推荐信
2014/07/07 职场文书
国庆横幅标语
2014/10/08 职场文书
学生检讨书
2015/01/27 职场文书
六年级作文之自救
2019/12/19 职场文书
Ajax请求超时与网络异常处理图文详解
2021/05/23 Javascript