前言
最近想做一个聊天,但是网上的很多都是不能实现的,要么就是缺少代码片段很难实现websocket的链接,更别说聊天了。自己研究了一番之后实现了这个功能。值得注意的是,我想在小程序中使用socket.io,不好使,可能是个人技术不到位的问题吧,没有实现。但是使用websocket可以完成这个功能。
环境准备
node @14.16.1
express @4.19.2
vsocde
HbuilderX
微信开发者工具
后端的依赖
后端代码
app.js文件的代码
// express具体使用看我提供个文章中有
const express = require('express')
const app = express()
const websocket = require('websocket').server
const http = require('http')
const httpServer = http.createServer().listen(3000,()=>{
console.log('http server is running at port 3000');
})
const websocketServer = new websocket({
httpServer: httpServer,
autoAcceptConnections: false
})
const conArr = []
websocketServer.on('request', function(request) {
// 这就是一次客户端发送的消息
// websocket 需要将这个链接保存起来
// 只要客户端和服务器没有断开,这个链接必须在
// 客户端与服务端的通信都是从这个链接上通信
const connection = request.accept()
// 每次接收一个链接,将它存放在数组里面
conArr.push(connection)
// 监听客户端发送的消息
connection.on('message', function(message) {
console.log(message);
// 发送消息给客户端(广播到各个客户端)
// 后面加上 utf8Data 编码
// 要将所有的链接全部发出去,才可以让每个客户端接收到其他传来的数据
for(let i = 0; i < conArr.length; i++) {
conArr[i].send(message.utf8Data)
}
})
})
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(8080, () => {
console.log('Express server is running at port 3000');
})
简单分析一下,websocket是基于http协议的所以要导入http模块,express和websocket监听的端口不一样,这样的话前端可以调用存储聊天信息的接口往数据库表中插入聊天信息,这样就可以完成聊天记录的存储,现在这个demo就是做了一个简单的websocket的链接和简陋的聊天界面。后续会完善一个开源项目完成聊天的功能、撤回和聊天记录回显的功能。
前端代码(uniapp)
<template>
<view>
姓名:<input type="text" v-model="name" />
话语:<input type="text" v-model="text" />
<button @click="onSumbit">发送</button>
</view>
</template>
<script>
export default{
data(){
return{
name:'',
text:''
}
},
onLoad() {
this.getLink()
},
methods:{
// 在页面或组件的方法中调用,初始化链接websocket
getLink(){
uni.connectSocket({
url: 'ws://127.0.0.1:3000',
success() {
console.log('WebSocket连接成功');
},
fail(err) {
console.error('WebSocket连接失败', err);
}
});
},
// 收到信息
getJieShouMessage(){
uni.onSocketMessage(function (res) {
console.log('收到消息:', res.data);
});
},
// websocket发生了错误
getErrorMessage(){
uni.onSocketError(function (err) {
console.error('WebSocket错误:', err);
});
},
// websocket关闭
getSocketGuanBi(){
uni.onSocketClose(function () {
console.log('WebSocket连接已关闭');
});
},
// 如果不需要的话就关闭websocket
getCloseThisLiaotian(){
uni.closeSocket({
code: 1000, // 关闭连接的状态码,可选
reason: '用户关闭连接', // 关闭连接的原因,可选
success() {
console.log('WebSocket连接已关闭');
},
fail(err) {
console.error('WebSocket关闭失败', err);
}
});
},
// 这个是点击发送信息
onSumbit(){
var that = this
let values={
name:this.name,
context:this.text
}
uni.sendSocketMessage({
data: JSON.stringify(values),
success() {
console.log('消息发送成功');
that.getJieShouMessage()
},
fail(err) {
console.error('消息发送失败', err);
}
});
}
}
}
</script>
注意
getLink(){
uni.connectSocket({
url: 'ws://127.0.0.1:3000',
success() {
console.log('WebSocket连接成功');
},
fail(err) {
console.error('WebSocket连接失败', err);
}
});
},
这段代码中,需要初始化调用,进行链接websocket,url是ws协议,线上的地址需要wss协议,具体可以参考微信官方的wss协议要求,我这demo是微信小程序。
效果图
通过上图可以看见可以及时的收到信息,前端拿到信息进行渲染就可以完成websocket的及时通讯了。