前言: 之前我写了一篇搭建简易的聊天室功能的文章,不知道的建议先去看一下: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);
$this->ws = new Swoole\WebSocket\Server('0.0.0.0', 9502, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);
$this->ws->set([
'ssl_cert_file' => '/www/server/panel/vhost/cert/114.55.29.146/fullchain.pem',
'ssl_key_file' => '/www/server/panel/vhost/cert/114.55.29.146/privkey.pem',
'worker_num' => 4,
'dispatch_mode' => 5,
]);
$this->ws->on('Open', [$this, "onOpen"]);
$this->ws->on('Message', [$this, "onMessage"]);
$this->ws->on('Close', [$this, "onClose"]);
$this->ws->start();
}
public function onOpen($ws, $request){
$info = [
'fd' => $request->fd,
'send_uid' => $request->get['send_uid'],
'this_uid' => $request->get['this_uid'],
'name' => $request->get['name']
];
$this->redis->set($request->get['this_uid']."_uid", json_encode($info));
}
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){
$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) {
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) {
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);
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后面,实际应用肯定会考虑更多,登录验证,信息安全,保存聊天记录进数据库等等。
如果您觉得本篇对你有帮助,可以点关注,给个赞,支持一下,过程有遇到什么问题也欢迎评论私信,进行交流
|