微信小程序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 相关文章推荐
JavaScript 获取事件对象的注意点
Jul 29 Javascript
javascript 获取所有id中包含某关键字的控件的实现代码
Nov 25 Javascript
JavaScript检测弹出窗口是否已经关闭的方法
Mar 24 Javascript
jQuery+css3实现转动的正方形效果(附demo源码下载)
Jan 27 Javascript
js中 计算两个日期间的工作日的简单实例
Aug 08 Javascript
javascript实现的上下无缝滚动效果
Sep 19 Javascript
jquery实现多次上传同一张图片
Jan 09 Javascript
使用yeoman构建angular应用的方法
Aug 14 Javascript
使用Vue开发一个实时性时间转换指令
Jan 17 Javascript
Vue无限滑动周选择日期的组件的示例代码
Jul 18 Javascript
vue 点击按钮实现动态挂载子组件的方法
Sep 07 Javascript
js array数组对象操作方法汇总
Mar 18 Javascript
深入探讨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
用PHP实现的生成静态HTML速度快类库
2007/03/31 PHP
PHP JSON格式数据交互实例代码详解
2011/01/13 PHP
PHP清除字符串中所有无用标签的方法
2014/12/01 PHP
关于扩展 Laravel 默认 Session 中间件导致的 Session 写入失效问题分析
2016/01/08 PHP
基于php伪静态的实现方法解析
2020/07/31 PHP
基于javascript 闭包基础分享
2013/07/10 Javascript
js中document.write使用过程中的一点疑问解答
2014/03/20 Javascript
javascritp添加url参数将参数加入到url中
2014/09/25 Javascript
javascript设置和获取cookie的方法实例详解
2016/01/05 Javascript
jQuery深拷贝Json对象简单示例
2016/07/06 Javascript
javascript遍历json对象的key和任意js对象属性实例
2017/03/09 Javascript
vue中用动态组件实现选项卡切换效果
2017/03/25 Javascript
解决vue-router中的query动态传参问题
2018/03/20 Javascript
JavaScript惰性载入函数实例分析
2019/03/27 Javascript
微信小程序用户授权弹窗 拒绝时引导用户重新授权实现
2019/07/29 Javascript
初步剖析C语言编程中的结构体
2016/01/16 Python
你应该知道的python列表去重方法
2017/01/17 Python
python numpy和list查询其中某个数的个数及定位方法
2018/06/27 Python
Python实现九宫格式的朋友圈功能内附“马云”朋友圈
2019/05/07 Python
Django forms表单 select下拉框的传值实例
2019/07/19 Python
python根据完整路径获得盘名/路径名/文件名/文件扩展名的方法
2020/04/22 Python
PIL.Image.open和cv2.imread的比较与相互转换的方法
2020/06/03 Python
python 视频下载神器(you-get)的具体使用
2021/01/06 Python
css3 box-shadow阴影(外阴影与外发光)图示讲解
2017/08/11 HTML / CSS
高尔夫球鞋、服装、手套和装备:FootJoy
2018/12/15 全球购物
高三自我鉴定怎么写
2013/10/19 职场文书
2014年客房服务员工作总结
2014/11/18 职场文书
2014年流动人口工作总结
2014/11/26 职场文书
小学教研工作总结2015
2015/05/13 职场文书
法人身份证明书
2015/06/18 职场文书
追悼词范文大全
2015/06/23 职场文书
党员干部学习三严三实心得体会
2016/01/05 职场文书
解决goland 导入项目后import里的包报红问题
2021/05/06 Golang
MySQL深度分页(千万级数据量如何快速分页)
2021/07/25 MySQL
攻击最高的10只幽灵系神奇宝贝,坚盾剑怪排第一,第五最为可怕
2022/03/18 日漫
java.util.NoSuchElementException原因及两种解决方法
2022/06/28 Java/Android