Online chat with Swoole

Posted by realchamp on Mon, 21 Oct 2019 16:36:50 +0200

Swoole and thinkp5 develop WebSocket online chat communication system

ThinkPHP needs to install the think Swoole composer package when using Swoole, provided that the system has been installed
Okay, Swoole PECL expansion
To install think swoole, execute the composer command in the project root directory of tp5:
1 composer require topthink/think-swoole

 

If you don't say much, go straight to the code:
To create a WebSocket.php controller:
(to confirm that the server is allowed to listen to the port, you need to add security group rules in pagoda environment.)
<?php
namespace app\home\controller;use think\swoole\Server;class WebSocket e
xtends Server{
protected $host = '0.0.0.0'; //Listen to all addresses protected $port = 9501; //Listen to port 9501
protected $serverType = 'socket';
protected $option = [
'worker_num'=> 4, //Set up started Worker Process number
'daemonize' => false, //Daemonization (online changed to true)
'backlog' => 128, //Listen queue length
'dispatch_mode' => 2, //Fixed mode to ensure that data sent from the same connection will only be sent to the same
worker Handle
//Heartbeat detection: traverse all connections every 60 seconds, and no messages are sent to the server within 10 minutes of forced shutdown.
Connection of data
'heartbeat_check_interval' => 60,
'heartbeat_idle_time' => 600
];
//Callback function when establishing connection
public function onOpen($server,$req)
{
$fd = $req->fd;//Client identity
$uid = $req->get['uid'];//Users delivered by the client id
$token = $req->get['token'];//User login delivered by client token
//Omit token validation logic... if (!$token){
$arr = array('status'=>2,'message'=>'token Expired');
$server->push($fd, json_encode($arr));
$server->close($fd);
return;
}
//Omit binding to user fd logic......
echo "user{$uid}Connection established,Identified as{$fd}\n";
}
//Callback function when receiving data
public function onMessage($server,$frame)
{
$fd = $frame->fd;
$message = $frame->data;
//Omission through fd Query users uid logic......
$uid = 666;
$data['uid'] = $uid;
$data['message'] = 'user'.$uid.'Sent:'.$message;
$data['post_time'] = date("m/d H:i",time());
$arr = array('status'=>1,'message'=>'success','data'=>$data);//Push to current connected users only
//$server->push($fd, json_encode($arr));
//Push to all connected users
foreach($server->connections as $fd) {
$server->push($fd, json_encode($arr));
}
}
//Callback function when connection is closed
public function onClose($server,$fd)
{
echo "Identification{$fd}Connection closed\n";
}
}

 

Front end demo page:
(omit the logic of the controller to judge the login status and allocate data...)
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><meta http-
equiv="X-UA-Compatible" content="IE=edge,chrome=1" /><meta name="viewpor
t" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-s
cale=1,user-scalable=no" /><title>Chat</title><link rel="stylesheet" typ
e="text/css" href="/static/liaotian/chat.css" /><script src="/static/liaotian/js/jquery.min.js"></script><script src="/static/liaotian/js/flexib
le.js"></script></head><body>
<header class="header">
<a class="back" href="javascript:history.back()"></a>
<h5 class="tit">chat online</h5>
<a href=""><div class="right">Sign out</div></a>
</header>
<!-- Chat content start-->
<div class="message"> </div>
<!-- Chat content end-->
<!-- bottom start-->
<div class="footer">
<img id="setbtn" src="/static/liaotian/images/hua.png" alt="" />
<img src="/static/liaotian/images/xiaolian.png" alt="" />
<input type="text" id="msg" value="" maxlength="300">
<p style="background: rgb(17, 79, 142);" id="sendBtn">Send out</p>
</div>
<!-- bottom end--></body></html><script src="http://apps.bdimg.com/lib
s/jquery/2.1.4/jquery.min.js"></script><script src="https://cdn.bootcss.
com/layer/3.1.0/layer.js"></script><script type="text/javascript">
$(function () {
var uid = 666;//Current user idvar token = 'abcdefg';//User token
//Determine whether the browser supports WebSocket
var supportsWebSockets = 'WebSocket' in window || 'MozWebSocket' in w
indow;
if (supportsWebSockets) {
//establish WebSocket Connection ( ip Change address to own host ip)
var ws = new WebSocket("ws://127.0.0.1:9501?uid="+uid+"&token="+t
oken);
ws.onopen = function () {
layer.msg('Server connection successful',{shade:0.1,icon:1,time:600});
};
ws.onerror = function () {
layer.msg('Server connection failed',{shade:0.1,icon:2,time:600});
};
ws.onmessage = function (evt) {
var data = $.parseJSON(evt.data);
//Error prompt
if(data.status != 1){
layer.alert(data.message,{icon:2});
return;
}
//Message return if (data.status==1 && data.data.message!='') {
var html = "";
if (data.data.uid == uid) {
html += "<div style='word-break:break-all' class=\"sho
w\"><div class=\"time\">"+data.data.post_time+"</div><div class=\"msg\">
<img src=\""+data.data.head_img+"\" alt=\"\" /><p><i clas=\"msg_input\">
</i>"+data.data.message+"</p></div></div>";
}else{
html += "<div style='word-break:break-all' class=\"sen
d\"><div class=\"time\">"+data.data.post_time+"</div><div class=\"msg\">
<img src=\""+data.data.head_img+"\" alt=\"\" /><p><i clas=\"msg_input\">
</i>"+data.data.message+"</p></div></div>";
}
}
$(".message").append(html);
setTimeout(function () {
($('.message').children("div:last-child")[0]).scrollIntoV
iew();//scroll up
},100);
};
ws.onclose = function (res) {
};
//Push button to send
$("#sendBtn").click(function () {
var contents = $("#msg").val().trim();if(contents == null || contents == ""){
layer.msg('Content is empty',{shade:0.1,icon:2,time:600});
return false;
}else{
ws.send(contents);
$("#msg").val("");
}
});
//Carriage return
$("#msg").keydown(function (evel) {
var that = $(this);
if (evel.keyCode == 13) {
evel.cancelBubble = true;
evel.preventDefault();
evel.stopPropagation();
var contents = that.val().trim();
if(contents == null || contents == ""){
layer.msg('Content is empty',{shade:0.1,icon:2,time:600});
return false;
}else{
ws.send(contents);that.val("");
}
}
});
}else{
layer.alert("Your browser does not support WebSocket!");
}
});</script>

 

Move the server to the project root directory to start the service:
php public/index.php Websocket/start
The path here is because I bound the home module as the default module, and the tp5 default is: php
public/index.php index/Websocket/start)
Open successfully. Check whether the port has been monitored:
lsof -i:9501

Topics: PHP JQuery Javascript socket