本文章使用webSocket + 微信小程序实现一个双方都在线的一对一聊天,服务端使用为宝塔。
在宝塔中,我们需要将我们会用到的端口号开启,会用到Redis,swoole,分别放行之后,我们就要创建文件夹并新建一个php文件 名字自起。
双击文件我们对其进行编辑
<?php
//创建WebSocket Server对象,监听0.0.0.0:9502端口
$ws = new Swoole\WebSocket\Server('0.0.0.0', 9502);
//实例化Redis
$redis = new Redis();
//对redis进行连接
$redis->connect('127.0.0.1','6379');
//监听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) {
//将我们从小程序端传递过来的数据转换成数组格式进行处理
$data = json_decode($frame->data,true);
//通过小程序端传递过来的类型进行处理
switch($data['type']){
//如果类型为连接
case "open" :
//将登录的用户昵称设为键,保存用户id
$redis->set($data['my'],$frame->fd);
break;
//如果类型为发送
case "send" :
//取出我们发送给对方的id
//【当前登陆用户为yuchen,我们要发送给miao,存进去的用户信息为yuchen信息,取出来的是miao信息】
//【当前登陆用户为miao,我们要发送给yuchen,存进去的用户信息为miao信息,取出来的是yuchen信息】
$toId = $redis->get($data['to']);
//将用户昵称和所要发送的消息返回给小程序端
$msg = [
'user' => $data['my'],
'msg' => $data['data']
];
//我们要将消息push给对方,也就是当前登录yuchen,push给miao
$ws->push($toId, json_encode($msg,true));
break;
default:
break;
}
});
//监听WebSocket连接关闭事件
$ws->on('Close', function ($ws, $fd) {
echo "client-{$fd} is closed\n";
});
$ws->start();
对进程添加守护和心跳检测
$ws->set(array(
'daemonize' => true, //守护进程
'heartbeat_idle_time' => 600, // 表示一个连接如果600秒内未向服务器发送任何数据,此连接将被强制关闭
'heartbeat_check_interval' => 60, // 表示每60秒遍历一次
));
接着下我们需要在小程序中进行编写
首先我们的封装一个连接,将小程序和服务器连接起来
open:function(){
let _this = this;
//建立连接
wx.connectSocket({
//对应ip及端口
url: 'wss://example.qq.com',
success:function(){
//监听连接事件
wx.onSocketOpen((result)=>{
let msg = {
'to' : 'miao', //对方是谁
'my' : 'yuchen', //我是谁
'type' : 'open' //当前状态
}
//向服务器发送信息,需要转换为json
_this.send(JSON.stringify(msg));
//接收服务器返回信息
_this.serverMsg();
})
}
})
}
封装发送信息,接收服务器返回信息,获取输入信息并发送方法
//发送信息
send:function(res){
//调用向服务器发送信息函数
wx.sendSocketMessage({
data : res
})
}
//获取输入框信息并发送
sendMyMsg:function(option){
let myMsg = option.detail.value.text;
let msg = {
'to' : 'miao', //发送给谁
'my' : 'yuchen', //我是谁
'type' : 'send', //当前状态
'data' : myMsg //发送信息
}
this.send(JSON.stringify(msg)); //调用发送方法,向服务器发送数据
let data = this.data.records; //将页面data内的数组records进行调用
//将用户名称及发送信息追加到数组中
data.push({
user : msg.my,
msg : myMsg
})
//进行数据传递
this.setData({
records : data
})
}
//接收服务器返回消息
serverMsg:function(){
let _this = this;
//调用接收函数,接收服务器返回数据
wx.onSocketMessage((result)=>{
//因为在数据库中返回的数据为json数据格式,因此我们需要在前台进行转义
let parseMsg = JSON.parse(result.data);
let data = _this.data.records; //调用页面data内的数组records
//接收到的数据追加到数组中
data.push({
user : parseMsg.user,
msg : parseMsg.msg
})
//数据传递
_this.setData({
records : data
})
})
}
到此,只需要在wxml页面进行循环展示即可。
<view>
<view>
<block wx:for="{{data}}">
<view>
<text>{{item.user}}:</text>
<text>{{item.msg}}</text>
</view>
</block>
</view>
<view>
<form action="" bindsubmit="sendMyMsg">
<input class="input" value="{{value}}" type="text" name="text"/>
<button size="mini" type="primary" form-type="submit">发送</button>
</form>
</view>
</view>