微信小程序websocket聊天室的实现示例代码


Posted in Javascript onFebruary 12, 2019

背景

最近做了一个微信小程序的即时通讯功能,之前我也做过node.js的websocket服务,不过是在web端应用的socket.io服务。小程序本身对http、websocket等连接均有诸多限制,所以这次项目选择了node.js自带的ws模块。

服务端

初始化一个node.js项目,引入ws模块

const webSocket = require('ws');

创建websocket实例,并设置监听端口

const wss = new webSocket.Server({
  port: 3001
});

定义wss实例方法,实现socket监听和信息发布。下面贴上简单的示例:

wss.on('connection', function connection(ws, req) {
  console.log('连接开启')
  
  //发生错误
  ws.on('error', function error(error) {
    console.log('error', error);
  });

  //断开连接
  ws.on('close', function close(close) {
    console.log( '已关闭');
  });

  ws.on('message', function message(message) {
    ws.send('客户端发来了一条消息')
  });

  //发送消息
  ws.send('连接已开启');
  ws.send(id + '已连接')
});

这样,一个简单的websocket服务就配置完成了。当然,问题远远不止这么简单。要想在小程序中进行通信,还需要解决下面几个问题。

域名

关于小程序服务端域名配置,小程序开发文档中如下提到

微信小程序websocket聊天室的实现示例代码

小程序请求地址只支持https或者wss协议,因此首先要配置的就是SSL证书。拿到SSL证书之后,在服务端做一下https的配置即可。

var fs = require('fs');
const options = {
  key: fs.readFileSync('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'utf8'),//证书地址
  cert: fs.readFileSync('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'utf8'),//证书地址
};
var https = require('https');
var server = https.createServer(options, app);

另外值得注意的是,websocket监听的端口号需要做一下代理,因为小程序如果不配置端口号时,所有请求的url都不可以带端口号。

多房间通信

先看一下广播的实现:

//广播方法
wss.broadcast = function broadcast(data) {
  wss.clients.forEach(function each(client) {
    client.send(data)
  });
};

wss对象的clients是一个存储着所有socket连接对象的数组,每条连接对象都可以调用各自的send方法发送信息。

在此基础上,我们可以进行一定的封装,用一个唯一的标识符映射到每一条socket连接,这样我们需要向特定的某个连接发送信息时,就可以找到该连接。

可以通过连接的url作为唯一标识:

let sockets = {}
 wss.on('connection', function connection(ws, req) {
    let id = req.url.slice(5);//截几位字符串根据自己实际获得的url来看
    sockets[id] = ws;
    ws.send(id + '已连接');
    ...

客户端每次连接时url后拼接一个唯一id,在服务端获取req.url并截取字符串拿到唯一id,并将该连接对象存储在全局的sockets下以便需要时使用。

在此基础上,可以继续封装诸如加入房间、离开房间、房间内通信、向特定用户私聊等功能,总体来说是对send方法的封装。值得注意的是send方法只能发送字符串,json对象需要转化成字符串再传入send。

下面是一个私聊的示例:

wss.notice = function notice(id, data, ws) {
  // 向指定id发送
  try {
    ws.send('正在发送...')
    var notice = JSON.stringify({
      type: 'notice',
      data: data
    })
    let target = sockets[id]
    if (target) {
      target.send('收到一条新消息')
      target.send(notice)
    } else {
      ws.send('目标信道已关闭')
    }
  } catch (err) {
    console.log(err)
  }
}

到这里,一个简单的聊天室服务端配置就基本完成了。

最终作品效果如下:

微信小程序websocket聊天室的实现示例代码

部分代码细节,请观众老爷们移步 微信小程序中聊天室的服务端和客户端配置示例 ^.^

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

Javascript 相关文章推荐
js隐藏与显示回到顶部按钮及window.onscroll事件应用
Jan 25 Javascript
js数组方法扩展实现数组统计函数
Apr 09 Javascript
JS获取iframe中marginHeight和marginWidth属性的方法
Apr 01 Javascript
js判断文件格式及大小的简单实例(必看)
Oct 11 Javascript
Vue.js 递归组件实现树形菜单(实例分享)
Dec 21 Javascript
vue快捷键与基础指令详解
Jun 01 Javascript
JavaScript初学者必看“new”
Jun 12 Javascript
详解vue 配合vue-resource调用接口获取数据
Jun 22 Javascript
easyui简介_动力节点Java学院整理
Jul 14 Javascript
基于Vue的SPA动态修改页面title的方法(推荐)
Jan 02 Javascript
Vue-cli项目部署到Nginx服务器的方法
Nov 01 Javascript
Vue项目打包、合并及压缩优化网页响应速度
Jul 07 Vue.js
深入探讨JavaScript的最基本部分之执行上下文
Feb 12 #Javascript
图文详解vue框架安装步骤
Feb 12 #Javascript
详解vue组件中使用路由方法
Feb 12 #Javascript
说说Vue.js中的functional函数化组件的使用
Feb 12 #Javascript
详解Vue用cmd创建项目
Feb 12 #Javascript
谈谈JavaScript中super(props)的重要性
Feb 12 #Javascript
微信小程序实现的自定义分享功能示例
Feb 12 #Javascript
You might like
mysql From_unixtime及UNIX_TIMESTAMP及DATE_FORMAT日期函数
2010/03/21 PHP
PHP表单递交控件名称含有点号(.)会被转化为下划线(_)的处理方法
2013/01/06 PHP
PHP中常用的转义函数
2014/02/28 PHP
ThinkPHP3.1新特性之Action参数绑定
2014/06/19 PHP
php实现最简单的MVC框架实例教程
2014/09/08 PHP
jQuery自动切换/点击切换选项卡效果的小例子
2013/08/12 Javascript
[原创]推荐10款最热门jQuery UI框架
2014/08/19 Javascript
14个有用的Jquery技巧分享
2015/01/08 Javascript
javascript图片预加载完整实例
2015/12/10 Javascript
详解JavaScript异步编程中jQuery的promise对象的作用
2016/05/03 Javascript
jQuery  ready方法实现原理详解
2016/10/19 Javascript
原生js FileReader对象实现图片上传本地预览效果
2020/03/27 Javascript
javascript数据类型中的一些小知识点(推荐)
2019/04/18 Javascript
gulp构建小程序的方法步骤
2019/05/31 Javascript
JavaScript实现轮播图效果代码实例
2019/09/28 Javascript
[01:03:18]DOTA2-DPC中国联赛 正赛 RNG vs Dynasty BO3 第一场 1月29日
2021/03/11 DOTA
深入解析Python编程中JSON模块的使用
2015/10/15 Python
浅谈编码,解码,乱码的问题
2016/12/30 Python
在Python的一段程序中如何使用多次事件循环详解
2017/09/07 Python
用Python进行简单图像识别(验证码)
2018/01/19 Python
python正则表达式及使用正则表达式的例子
2018/01/22 Python
python如何获取当前文件夹下所有文件名详解
2019/01/25 Python
python+adb命令实现自动刷视频脚本案例
2020/04/23 Python
使用pymysql查询数据库,把结果保存为列表并获取指定元素下标实例
2020/05/15 Python
Python爬取数据并实现可视化代码解析
2020/08/12 Python
python实现视频压缩功能
2020/12/18 Python
jupyter 添加不同内核的操作
2021/02/06 Python
HTML5混合开发二维码扫描以及调用本地摄像头
2017/12/27 HTML / CSS
制冷与电控专业应届生求职信
2013/11/11 职场文书
2014年应急管理工作总结
2014/11/26 职场文书
2014年小学体育工作总结
2014/12/11 职场文书
三潭印月的导游词
2015/02/12 职场文书
2015年世界急救日宣传活动方案
2015/05/06 职场文书
建国大业电影观后感
2015/06/01 职场文书
启迪人心的励志语录:脾气永远不要大于本事
2020/01/02 职场文书
如何利用JavaScript实现二叉搜索树
2021/04/02 Javascript