php swoole4 用WebSocket服务器搭建简易的点对点一对一的聊天功能进阶版
前言:
之前我写了一篇搭建简易的聊天室功能的文章,不知道的建议先去看一下:https://blog.csdn.net/qq_36303853/article/details/119958945
这时候好学的小伙伴就会问了,那怎么实现一对一的聊天呢?
前提
注:这里的用的redis保存用户信息,你也可以用mysql数据库,我提供的只是思路,方法不唯一,能实现就行
- 一台服务器
- 安装swoole4
- php>=7.2
- 安装rerdis(我这里用的redis,你也可以用mysql数据库)
- 宝塔和阿里云分别开放对应端口(我这里用的9502)
- 一个域名(我这里是配置了ssl的,没有配置ssl的代码跟着改就可以了,别问我怎么改,之前的文章已经写了,不知道的回去看看吧)
代码实现
WS.php服务端代码
<?php
class WS{
private $ws = null;
private $redis = null;
public function __construct(){
$this->redis = new Redis();
$this->redis->connect('127.0.0.1', 6379);
//创建WebSocket Server对象,监听0.0.0.0:9502端口
$this->ws = new Swoole\WebSocket\Server('0.0.0.0', 9502, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);
// $this->ws = new Swoole\WebSocket\Server('0.0.0.0', 9502);
//配置ssl文件路径
$this->ws->set([
'ssl_cert_file' => '/www/server/panel/vhost/cert/114.55.29.146/fullchain.pem', // worker process num
'ssl_key_file' => '/www/server/panel/vhost/cert/114.55.29.146/privkey.pem',
// 'task_worker_num' => 4//设置异步任务的工作进程数量
'worker_num' => 4,
'dispatch_mode' => 5, //uid dispatch
]);
//监听WebSocket连接打开事件
$this->ws->on('Open', [$this, "onOpen"]);
//监听WebSocket消息事件
$this->ws->on('Message', [$this, "onMessage"]);
//监听WebSocket连接关闭事件
$this->ws->on('Close', [$this, "onClose"]);
//启动服务器
$this->ws->start();
}
public function onOpen($ws, $request){
// var_dump($request->fd, $request->get['uid']);
$info = [
'fd' => $request->fd,
'send_uid' => $request->get['send_uid'],
'this_uid' => $request->get['this_uid'],
'name' => $request->get['name']
];
//保存用户信息进redis
$this->redis->set($request->get['this_uid']."_uid", json_encode($info));
// $ws->push($request->fd, "欢迎客户端: {$request->fd}\n");
}
public function onMessage($ws, $frame){
$data = json_decode($frame->data, true);//获取前端传过来的数据
$send_info = json_decode($this->redis->get($data['send_uid'] . '_uid'), true);//获取接收方数据
$ws->push($frame->fd, json_encode($data));//发给自己
$data['name'] = urldecode($data['name']);//中文编码问题
if($send_info){
/*
如果 A 和 B 在一个页面聊天,C 又给 A 发了一条消息,这样 A 和 B 的聊天列表里面,
A 也会收到 C 发送的消息,因为 A 满足了'在线'的要求,
所以在前端接收消息那里需要判断推送给自己的消息
这样就知道只要你在聊天页面就能收到所有人的消息,就可以实现一个你在聊天的过程中,
顶部弹出一个提示框 【孙某人给您发了一条消息,请注意查收哦!】
*/
$ws->push($send_info['fd'], json_encode($data));//发给接收方
}
}
public function onClose($ws, $fd){
echo "客服端:{$fd} 关闭\n";
}
}
new WS();
static/chat.html客户端代码
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>简易聊天室</title>
</head>
<div id="welcome"></div>
<input type="text" id="input"/>
<br />
<button type="buton" onclick="send()">发送</button>
<div id="message"></div>
<body>
</body>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
var wsServer = 'wss://xiangyu.huangzhongxin.cn:9502' window.location.search;
var websocket = null;
var lock = false;
$(function(){
relink();
})
function link(){
websocket = new WebSocket(wsServer);
websocket.onopen = function (res) {
console.log(11)
$("#welcome").html("<h1>连接成功!欢迎</h1>");
};
websocket.onclose = function (res) {
// $("#message").append("<h3>连接关闭</h3>");
websocket.close();
relink();
};
websocket.onmessage = function (res) {
var request =new UrlSearch();
console.log(request,11);
var info = JSON.parse(res.data);
console.log(info,22);
if(request['this_uid'] == JSON.parse(res.data)['this_uid']){
$("#message").append("<h3>我说:" info['message'] "</h3>")
}else if(request['this_uid'] == JSON.parse(res.data)['send_uid'] && request['send_uid'] == JSON.parse(res.data)['this_uid']){
$("#message").append("<h3>" info['name'] "对你说:" info['message'] "</h3>")
}
};
websocket.onerror = function (res) {
// $("#message").append("<h3>" res "</h3>");
websocket.close();
relink();
};
}
function send(){
var request = new UrlSearch(); //实例化
request['message'] = $('#input').val();
console.log(JSON.stringify(request))
websocket.send(JSON.stringify(request));
}
function UrlSearch()
{
var name,value,res;
var str=location.href; //取得整个地址栏
var num=str.indexOf("?")
str=str.substr(num 1); //取得所有参数 stringvar.substr(start [, length ]
var arr=str.split("&"); //各个参数放到数组里
for(var i=0;i < arr.length;i ){
num=arr[i].indexOf("=");
if(num>0){
name=arr[i].substring(0,num);
value=arr[i].substr(num 1);
this[name]=value;
}
}
}
function relink(){
if(lock){
return false;
}
lock = true;
setTimeout(function(){
link();
lock = false;
}, 1000)
}
</script>
</html>
启动
-
启动服务端
注:如果开启不了可能是9502端口被占用了,杀死即可netstat -anp | grep 9502 //查看端口号 9502
kill -9 4663 //杀死进程
-
浏览器分别开启多个客户端窗口,进行聊天
域名/static/chat.html?send_uid=1&this_uid=2&name=姓名
结果
- 可以看出,两个人可以正常进行聊天,而第三者无法插足。
- 这里
this_uid
指当前用户uid,name
指当前用户的姓名,send_uid
指的是接受信息人的uid - 当然我这里只是为了好理解,将信息都拼接到url后面,实际应用肯定会考虑更多,登录验证,信息安全,保存聊天记录进数据库等等。
如果您觉得本篇对你有帮助,可以点关注,给个赞,支持一下,过程有遇到什么问题也欢迎评论私信,进行交流
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgekhkg
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01