How to develop a WebSocket online chat communication system?Swoole and TP are good

Keywords: PHP JQuery Javascript socket

ThinkPHP using Swoole requires the think-swoole Composer package to be installed, provided the Swoole PECL extension is installed on the system

Install think-swoole by executing the composer command in the project root directory of tp5:

composer require topthink/think-swoole

Say nothing but code directly:

Create a new WebSocket.php controller:

(listening ports confirm server release, pagoda environments also need to add security group rules)

<?php
 
namespace app\home\controller;
use think\swoole\Server;
class WebSocket extends Server
{
    protected $host = '0.0.0.0'; //Listen on all addresses
    protected $port = 9501; //Listen on port 9501
    protected $serverType = 'socket';
    protected $option = [ 
        'worker_num'=> 4, //Set the number of Worker processes started
        'daemonize'    => false, //Daemon (go online to true)
        'backlog'    => 128, //Listen Queue Length
        'dispatch_mode' => 2, //Fixed mode to ensure that data from the same connection will only be processed by the same worker
 
        //Heart beat detection: traverse all connections every 60 seconds, forcing connections that do not send any data to the server to be closed for 10 minutes
        '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'];//User id passed by client
        $token = $req->get['token'];//Client-passed user login 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 fd logic to user...
        echo "user{$uid}Connection established,Identify as{$fd}\n";
    }
 
    //Callback function when receiving data
    public function onMessage($server,$frame)
    {
        $fd = $frame->fd;
        $message = $frame->data;
 
        //Omit querying user uid logic via fd...
        $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 user 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 presentation page:

(Omit the controller to determine login status, assign data logic...)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>Chat</title>
<link rel="stylesheet" type="text/css" href="/static/liaotian/chat.css" />
<script src="/static/liaotian/js/jquery.min.js"></script>
<script src="/static/liaotian/js/flexible.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/libs/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 id
    var token = 'abcdefg';//User token
 
    //Determine whether the browser supports WebSocket s
    var supportsWebSockets = 'WebSocket' in window || 'MozWebSocket' in window;
    if (supportsWebSockets) {
        //Set up a WebSocket connection (ip address replaced with your own host ip)
        var ws = new WebSocket("ws://127.0.0.1:9501?uid="+uid+"&token="+token);
        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 Tips
            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=\"show\"><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=\"send\"><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]).scrollIntoView();//scroll up
            },100);
        };
        ws.onclose = function (res) {
            
        };
        //Button 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("");
            }
        });
        //Enter Send
        $("#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 it WebSocket!");
    }
});
</script>

Server moved to project root to open service:

php public/index.php Websocket/start

The path here is because I have bound the home module as the default module and tp5 defaults to php public/index.php index/Websocket/start)

Open successfully, view port has been listened on:

lsof -i:9501

I believe that many phper s will encounter some problems and bottlenecks when they are advanced. They write too much business code without a sense of direction and don't know where to start to improve. I have sorted out some data about this, including but not limited to: distributed architecture, high scalability, high performance, high concurrency, server performance tuning, TP6, laravel, YII2, Redis, Swoole, Swoft, Kafka, Mysql tuningAdvanced and advanced dry goods needs such as chemicals, shell scripts, Docker, micro-services, Nginx, etc. can be shared free of charge to everyone, need Please click here

Posted by mark_h_uk on Thu, 07 Nov 2019 10:37:32 -0800