首頁 > php框架 > Workerman > 主體

談談利用workerman實現即時聊天功能的方法

青灯夜游
發布: 2021-02-22 17:57:33
轉載
5342 人瀏覽過

本篇文章為大家介紹一下使用workerman實作即時聊天的方法。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。

談談利用workerman實現即時聊天功能的方法

相關推薦:《workerman教學

開發文件:http://doc2.workerman.net/

下載伺服器端安裝檔:

 有windows版和linux版兩個版本,我下載的linux版,在windows上也可以運作。

開啟後有這些檔案:

把這個檔案放在伺服器上或專案都可以,需要執行的就是最後一個start_for_win.bat文件。

運行成功。

修改start_gateway.php檔:

<?php
/**
 * This file is part of workerman.
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the MIT-LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @author walkor<walkor@workerman.net>
 * @copyright walkor<walkor@workerman.net>
 * @link http://www.workerman.net/
 * @license http://www.opensource.org/licenses/mit-license.php MIT License
 */
use \Workerman\Worker;
use \Workerman\WebServer;
use \GatewayWorker\Gateway;
use \GatewayWorker\BusinessWorker;
use \Workerman\Autoloader;

// 自动加载类
require_once __DIR__ . &#39;/../../vendor/autoload.php&#39;;

// gateway 进程,这里使用Text协议,可以用telnet测试
$gateway = new Gateway("websocket://0.0.0.0:8282");
// gateway名称,status方便查看
$gateway->name = &#39;YourAppGateway&#39;;
// gateway进程数
$gateway->count = 4;
// 本机ip,分布式部署时使用内网ip
$gateway->lanIp = &#39;127.0.0.1&#39;;
// 内部通讯起始端口,假如$gateway->count=4,起始端口为4000
// 则一般会使用4000 4001 4002 4003 4个端口作为内部通讯端口
$gateway->startPort = 2900;
// 服务注册地址
$gateway->registerAddress = &#39;127.0.0.1:1238&#39;;

// 心跳间隔
$gateway->pingInterval = 60;
// 心跳数据
$gateway->pingData = &#39;{"type":"ping"}&#39;;

/*
// 当客户端连接上来时,设置连接的onWebSocketConnect,即在websocket握手时的回调
$gateway->onConnect = function($connection)
{
    $connection->onWebSocketConnect = function($connection , $http_header)
    {
        // 可以在这里判断连接来源是否合法,不合法就关掉连接
        // $_SERVER[&#39;HTTP_ORIGIN&#39;]标识来自哪个站点的页面发起的websocket链接
        if($_SERVER[&#39;HTTP_ORIGIN&#39;] != &#39;http://kedou.workerman.net&#39;)
        {
            $connection->close();
        }
        // onWebSocketConnect 里面$_GET $_SERVER是可用的
        // var_dump($_GET, $_SERVER);
    };
};
*/

// 如果不是在根目录启动,则运行runAll方法
if(!defined(&#39;GLOBAL_START&#39;))
{
    Worker::runAll();
}
登入後複製

第24行,把tcp協定改為websocket協定;

第38行和40行,設定伺服器向客戶端發送的心跳時間,偵測客戶端是否連接,未連接將會斷開。

下面的內容都是預設註解掉的,依照自己的需求開啟或修改。

再次執行start_for_win.bat檔案:

# 協定就變成websocket協定了,現在就可以做專案內的操作了。

還需要再下載一個檔案:https://github.com/walkor/GatewayClient

# 把這幾個檔案放進thinkphp的extend文件夾下(我使用的是thinkphp5.0版):

 在Gateway.php的檔案中方法幾乎都寫好了。

寫了一個簡單的前端頁面:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title></title>
    </head>
    <body>
        <ul id="msgUl">
            <li>ws://127.0.0.1:8282</li>
        </ul>
        <input type="" name="" id="sendValue" value="" />
        <button type="button" id="sendButton">发送</button>

        <div style="margin-top: 100px">
            {volist name="msg" id="vo" empty="这里没有数据" key =&#39;s&#39;}
                    <br/>
                <span>{$vo.user_name}:</span>
                <span>{$vo.msg}</span>
                <span>{$vo.createtime}</span>
                    <br/>
              {/volist}
        </div>

        <script src="http://www.zhihuapinpai.com/static/index/js/jquery-1.11.3.min.js"></script>
        <script>
            // var ws = new WebSocket("ws://123.56.216.232:8282");
            var ws = new WebSocket("ws://127.0.0.1:8282");

            ws.onopen = function() {
                $(&#39;#msgUl&#39;).append(&#39;<li>已连接上...</li>&#39;)
                sendValue();
            };

            ws.onmessage = function(evt) {
                $(&#39;#msgUl&#39;).append(&#39;<li>接收到:&#39; + evt.data + &#39;</li>&#39;)
                var obj = JSON.parse(evt.data);
                if (obj.type == &#39;onConnect&#39;) {
                    // 连接成功
                    $(&#39;#msgUl&#39;).append(&#39;<li>client_id:&#39; + obj.client_id + &#39;</li>&#39;)
                    $.ajax({
                        type:"POST",
                        url:"/index.php/api/Index/user_bind",
                        data:{
                            client_id:obj.client_id
                        },
                        dataType: "html",
                        success: function(data){
                            console.log(&#39;成功&#39;)
                        }
                    });
                } else if (obj.type == &#39;ping&#39;) {
                    // 心跳检测 不做任何处理
                } else if (obj.type == &#39;chatGroup&#39;) {
                    // 群组聊天
                    $(&#39;#msgUl&#39;).append(&#39;<li>接收到:&#39; + evt.data + &#39;</li>&#39;)
                }
            };

            ws.onclose = function() {
                // console.log(&#39;连接已关闭...&#39;);
                $(&#39;#msgUl&#39;).append(&#39;<li>连接已关闭...</li>&#39;)
            };

            function sendValue() {
                $(&#39;#sendButton&#39;).click(function() {
                    var thisValue = $(&#39;#sendValue&#39;).val();
                    if (thisValue) {
                        ws.send(thisValue);
                        $(&#39;#msgUl&#39;).append(&#39;<li>发送数据:&#39; + thisValue + &#39;</li>&#39;)
                        $.get("/index.php/api/Index/send_msg/msg/"+thisValue,function (data,status) {
                            console.log(&#39;成功:&#39;+thisValue)
                        });
                    }
                })
            }
        </script>
    </body>
</html>
登入後複製

 第42—52行把client_id傳到後台,與使用者表中使用者進行綁定。

後台代碼:

<?php
namespace app\api\controller;
use think\Controller;
use GatewayClient\Gateway;
use think\Db;


class Index extends Controller
{

    public function websocket(){
        $where=[];
        $user_id=1;
        $where[&#39;from_id|to_id&#39;]=$user_id;
        $msg=Db::name(&#39;msg&#39;)->where($where)->select();
        foreach ($msg as $key=>$val){
            $msg[$key][&#39;createtime&#39;]=date(&#39;Y-m-d H:i:s&#39;,$val[&#39;createtime&#39;]);
            $msg[$key][&#39;user_name&#39;]=Db::name(&#39;user&#39;)->where([&#39;id&#39;=>$val[&#39;from_id&#39;]])->value(&#39;name&#39;);
        }
        $this->assign(&#39;msg&#39;,$msg);
        return view();
    }

    //绑定用户
    public function user_bind($user_id=1){
        //$user_id=1; //发送人用户id
        $client_id = input(&#39;post.client_id&#39;);
//        $user=Db::name(&#39;user&#39;)->where([&#39;id&#39;=>$user_id])->find();
        Gateway::bindUid($client_id, 1);
        return $client_id;
    }

    //发送信息
    public function send_msg(){
        $msg=input(&#39;msg&#39;);
        if($msg){
            $data=[
              &#39;msg&#39;=>$msg,
              &#39;from_id&#39;=>1,
              &#39;to_id&#39;=>2,
              &#39;createtime&#39;=>time()
            ];
            Db::name(&#39;msg&#39;)->insert($data);
            Gateway::sendToUid(1,$msg);
            Gateway::sendToUid(2,$msg);
        }
        return &#39;success&#39;;
    }

}
登入後複製

發送訊息存入資料庫,頁面顯示即可。

更多電腦程式相關知識,請造訪:程式設計影片! !

以上是談談利用workerman實現即時聊天功能的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:cnblogs.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!