WebSocket+微信小程序一对一聊天
前言
一、搭建服务端
在我们的宝塔中创建一个以 .php 结尾的文件,将下面的内容放进去,
<?php //创建WebSocket Server对象,监听0.0.0.0:9502端口 $ws = new SwooleWebSocketServer(0.0.0.0, 9502); //实例化Redis $redis = new Redis(); //对redis进行连接 $redis->connect(127.0.0.1,6379); $ws->set([ heartbeat_idle_time => 600, // 表示一个连接如果600秒内未向服务器发送任何数据,此连接将被强制关闭 heartbeat_check_interval => 60, // 表示每60秒遍历一次 daemonize => true // 守护进程 ]); //监听WebSocket连接打开事件 $ws->on(Open, function ($ws, $request) { //向小程序端进行一个连接返回,告知用户已经连接上服务器,返回值需要转为json数据格式 $ws->push($request->fd, json_encode([msg=>用户已连接],true)); }); //监听WebSocket消息事件 $ws->on(Message, function ($ws, $frame) use ($redis) { $res = json_decode($frame->data,true); //print_r($res); if($res[type]==article)$ws->push($frame->fd,json_encode([msg=>心跳监测])); if($res[type]==open)$redis->set($res[me],$frame->fd); if($res[type]==send){ $to = $redis->get($res[to]); $data = [ msg=>$res[msg], style=>$res[me], error_code=>0 ]; $ws->push($to,json_encode($data)); } }); //监听WebSocket连接关闭事件 $ws->on(Close, function ($ws, $fd) { echo "client-{$fd} is closed "; }); $ws->start();
二、搭建客服端
可以在onLoad中直接写入,也可以封装起来,通过wx.connectSocket来建立客服端和服务端的一个连接
然后创建一个心跳监测方法,自动向服务端发送状态。
webSocketXin(time = 3000, status = true) { var timing; if (status == true) { timing = setInterval(function () { console.log("当前心跳已重新连接"); //循环执行代码 wx.sendSocketMessage({ data: JSON.stringify({ type: active }), fail(res) { //关闭连接 wx.closeSocket(); //提示 wx.showToast({ title: 当前聊天已断开, icon: none }); clearInterval(timing); console.log("当前心跳已关闭"); } }); }, time) //循环时间,注意不要超过1分钟 } else { //关闭定时器 clearInterval(timing); console.log("当前心跳已关闭"); } },
创建一个发送方法向服务端发送消息,并且使用wx.onSocketMessage监听服务端收到的消息,将消息入栈存入我们创建好的空数组。
//发送信息 send:function(res){ //调用向服务器发送信息函数 wx.sendSocketMessage({ data : res }) } //获取输入框信息并发送 sendMyMsg:function(option){ let myMsg = option.detail.value.text; let msg = { me : user, //我是谁 to : server, //发送给谁 type : send, //当前状态 data : myMsg //发送信息 } this.send(JSON.stringify(msg)); //调用发送方法,向服务器发送数据 let data = this.data.list; //将页面data内的数组records进行调用 //将用户名称及发送信息追加到数组中 data.push({ user : msg.my, msg : myMsg }) //进行数据传递 this.setData({ records : data }) } //接收服务器返回消息 serverMsg:function(){ //调用接收函数,接收服务器返回数据 wx.onSocketMessage((result)=>{ //因为在数据库中返回的数据为json数据格式,因此我们需要在前台进行转义 let parseMsg = JSON.parse(result.data); let data = _this.data.data; //调用页面data内的数组records //接收到的数据追加到数组中 data.push({ user : parseMsg.user, msg : parseMsg.msg }) //数据传递 this.setData({ list: data }) }) }
在wxml页面进行循环数组,将监听到的消息数据展示出来
<l-input label="消息" placeholder="请输入要发送的消息" bind:lininput=getMsg style="float: left;" /> <l-button type=success bind:lintap="send">发送</l-button> <view style="clear: left;"> <block wx:for="{ {list}}" wx:key="index"> <view wx:if="{ {item.style==undefined}}"> { {item.msg}} </view> <view wx:else> <!-- 判断条件,判罚是否为自己发送的内容,是在右边出现,不是在左边出现 --> <view wx:if="{ {item.style==***}}"> <view style="text-align: right;"> { {item.msg}}:{ {item.style}} </view> </view> <view wx:else style="text-align: left;"> { {item.style}}:{ {item.msg}} </view> </view> </block> </view>