PHP8.1.21版本已发布
vue8.1.21版本已发布
jquery8.1.21版本已发布

谈谈利用workerman实现即时聊天功能的方法

青灯夜游
青灯夜游 转载
2021-02-03 18:26:23 5070浏览

本篇文章给大家介绍一下使用workerman/" target="_blank">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的文件中方法几乎都写好了。

写了一个简单的前端页面:

nbsp;html>

    
        <meta>
        <meta>
        <meta>
        <title></title>
    
    
        
                
  • ws://127.0.0.1:8282
  •         
                          
            {volist name="msg" id="vo" empty="这里没有数据" key ='s'}                     
                {$vo.user_name}:                 {$vo.msg}                 {$vo.createtime}                     
              {/volist}         
        <script></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>已连接上...&#39;)                 sendValue();             };             ws.onmessage = function(evt) {                 $(&#39;#msgUl&#39;).append(&#39;<li>接收到:&#39; + evt.data + &#39;&#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;&#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;&#39;)                 }             };             ws.onclose = function() {                 // console.log(&#39;连接已关闭...&#39;);                 $(&#39;#msgUl&#39;).append(&#39;<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;&#39;)                         $.get("/index.php/api/Index/send_msg/msg/"+thisValue,function (data,status) {                             console.log(&#39;成功:&#39;+thisValue)                         });                     }                 })             }         </script>     

 第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]['createtime']=date('Y-m-d H:i:s',$val['createtime']);
            $msg[$key]['user_name']=Db::name('user')->where(['id'=>$val['from_id']])->value('name');
        }
        $this->assign('msg',$msg);
        return view();
    }

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

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

}

发送消息存入数据库,页面显示即可。

更多计算机编程相关知识,请访问:编程视频!!

声明:本文转载于:博客园,如有侵犯,请联系admin@php.cn删除