本文有相对完整的集成代码和前端测试代码,以及服务器启动注意事项

一、后端(laravel5.5

1、composer安装Workerman

composer require workerman/workerman

2、生成执行命令,执行后会在App\Console\Command文件夹下生成一个Workerman.php的文件

php artisan make:command Workerman

3、打开Workerman.php的文件,并修改代码,如下:

argument('action');
        $argv[1] = $arg;
        $argv[2] = $this->option('daemonize') ? '-d' : '';//该参数是以daemon(守护进程)方式启动

        global $text_worker;
        // 创建一个Worker监听9991端口,使用websocket协议通讯
        $text_worker = new Worker("websocket://0.0.0.0:9991");
        $text_worker->uidConnections = array();//在线用户连接对象
        $text_worker->uidInfo = array();//在线用户的用户信息
        // 启动4个进程对外提供服务
        $text_worker->count = 1;
        //当启动workerman的时候 触发此方法
        $text_worker->onWorkerStart =function(){
            //监听一个内部端口,用来接收服务器的消息,转发给浏览器
            $inner_text_worker = new Worker('text://127.0.0.1:5678');
            $inner_text_worker->onMessage = function($connection_admin, $data)
            {
                global $text_worker;
                // $data数组格式,里面有uid,表示向那个uid的页面推送数据
                $buffer = json_decode($data, true);
                //var_dump($buffer);
                $to_uid = $buffer['to_uid'];
                //var_dump($to_uid);

                // 通过workerman,向uid的页面推送数据
                if(isset($text_worker->uidConnections[$to_uid])){
                    $connection = $text_worker->uidConnections[$to_uid];
                    $ret = $connection->send($data);
                } else {
                    var_dump($to_uid . ': not define');
                    $ret = false;
                }
                // 返回推送结果
                $connection_admin->send($ret ? 'ok' : 'fail');
            };

            $inner_text_worker->listen();

            // 进程启动后设置一个每10秒运行一次的定时器
            Timer::add(10, function(){
                global $text_worker;
                $time_now = time();
                foreach($text_worker->connections as $connection) {
                    // 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间
                    if (empty($connection->lastMessageTime)) {
                        $connection->lastMessageTime = $time_now;
                        continue;
                    }
                    // 上次通讯时间间隔大于心跳间隔,则认为客户端已经下线,关闭连接
                    if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) {
                        var_dump("delete:" . $connection->uid);
                        unset($text_worker->uidConnections["{$connection->uid}"]);
                        $connection->close();
                    }
                }
            });
        };
        //当浏览器连接的时候触发此函数
        $text_worker->onConnect = function($connection) {
        };
        //向用户发送信息的时候触发
        //$connection 当前连接的人的信息 $data 发送的数据
        $text_worker->onMessage = function($connection,$data){
            // 给connection临时设置一个lastMessageTime属性,用来记录上次收到消息的时间
            $connection->lastMessageTime = time();
            // 其它业务逻辑...
            $data = json_decode($data, true);
            if($data['type']=='login') {
                $this->create_uid($connection,$data);
            }
            if($data['type']=='send_message'){
                $this->send_message($connection,$data);
            }
        };
        //浏览器断开链接的时候触发
        $text_worker->onClose = function($connection){};
        Worker::runAll();
    }

    //创建uid方法
    public function create_uid($connection,$data){
        global $text_worker;
        $connection->uid = $data['uid'];
        //保存用户的uid
        $text_worker->uidConnections["{$connection->uid}"] = $connection;
        //向自己的浏览器返回创建成功的信息
        $connection->send(json_encode([
            "uid"=>$connection->uid,
            "msgType"=>'text',
            "content"=>'聊天创建成功,您可以开发发送消息了'
        ]));
    }

    public function send_message($connection,$data) {
        global $text_worker;
        if(isset($data['to_uid'])){
            if(isset($text_worker->uidConnections["{$data['to_uid']}"])){
                $to_connection=$text_worker->uidConnections["{$data['to_uid']}"];
                $to_connection->send(json_encode([
                    "uid"=>$data['uid'],
                    "msgType"=>$data['msgType'],
                    "content"=>$data['message']
                ]));
            }
        }
    }
}

4、修改App\Console下面的Kernel.php文件,如下:

protected $commands = [
        Commands\Workerman::class,
];

5、启动Workerman服务,启动命令如下:

php artisan Workerman start

laravel集成Workerman搭建websocket服务,前端调用,服务器启动插图

出现上图所示,则表示启动成功

二、前端如何连接Workerman服务(websocket)服务

1、新建两个html页面用于测试,当然,也可以直接在浏览器打开F12在console里面测试,我这里有写好的页面,直接换个ws地址就能用,支持发送文字,图片

37websoket.html




  
  
  
   


  
    
      
        
          
            laravel集成Workerman搭建websocket服务,前端调用,服务器启动插图(1)
          
          
            {{http://blog.csdn.net/wwsseeddrrff/article/details/item.content}}
          
          
            laravel集成Workerman搭建websocket服务,前端调用,服务器启动插图(2)
          
        
        
          
            {{http://blog.csdn.net/wwsseeddrrff/article/details/item.content}}
          
          
            laravel集成Workerman搭建websocket服务,前端调用,服务器启动插图(2)
          
          
            laravel集成Workerman搭建websocket服务,前端调用,服务器启动插图(3)
          
        
      
    
    
  	
        
        
          
          发消息
          
        
    
  
  


  html,body{margin: 0;padding:0}
  #app{height: 100vh;background: #F5F5F5}
  .left-box {display: flex;flex-shrink: 0;margin-bottom: 10px;margin-top: 10px;}
  .right-box {display: flex;justify-content: flex-end;width: 100%;margin-bottom: 10px;margin-top: 10px;}
  .msg-box-l{background: #fff;max-width: 80%;padding: 8px;border-top-right-radius: 10px;border-bottom-right-radius: 10px;border-bottom-left-radius: 10px;margin-left: 10px;margin-top: 10px;box-shadow: 0 2px 11px -7px rgba(2,66,58,.5)}
  .msg-box-r{background: #95EC69;max-width: 80%;padding: 8px;border-top-left-radius: 10px;border-bottom-right-radius: 10px;border-bottom-left-radius: 10px;margin-right: 10px;margin-top: 10px;box-shadow: 0 2px 11px -7px rgba(2,66,58,.5)}
  .msg-text-l{color: #000;word-break: break-all;}
  .msg-text-r{color: #000;word-break: break-all;}
.ta{resize: none;width: 100%;height: 100px;position: fixed;bottom: 20px;}
.ta1{resize: none;width: 70%;margin-left:5%;height: 100px;position: fixed;bottom: 20px;}
.r-b{display: flex;align-items: flex-end;flex-direction: column;}
.send-btn{background: #4287FD;color: #fff;padding: 5px 10px;margin: 10px;}
.input-file {
    width: 0.1px; 
    height: 0.1px; 
    opacity: 0; 
    overflow: hidden; 
    position: absolute; 
    z-index: -1;


38websoket.html




  
  
  
   


  
    
      
        
          
            laravel集成Workerman搭建websocket服务,前端调用,服务器启动插图(1)
          
          
            {{http://blog.csdn.net/wwsseeddrrff/article/details/item.content}}
          
          
            laravel集成Workerman搭建websocket服务,前端调用,服务器启动插图(2)
          
        
        
          
            {{http://blog.csdn.net/wwsseeddrrff/article/details/item.content}}
          
          
            laravel集成Workerman搭建websocket服务,前端调用,服务器启动插图(2)
          
          
            laravel集成Workerman搭建websocket服务,前端调用,服务器启动插图(3)
          
        
      
    
    
  	
        
        
          
          发消息
          
        
    
  
  


  html,body{margin: 0;padding:0}
  #app{height: 100vh;background: #F5F5F5}
  .left-box {display: flex;flex-shrink: 0;margin-bottom: 10px;margin-top: 10px;}
  .right-box {display: flex;justify-content: flex-end;width: 100%;margin-bottom: 10px;margin-top: 10px;}
  .msg-box-l{background: #fff;max-width: 80%;padding: 8px;border-top-right-radius: 10px;border-bottom-right-radius: 10px;border-bottom-left-radius: 10px;margin-left: 10px;margin-top: 10px;box-shadow: 0 2px 11px -7px rgba(2,66,58,.5)}
  .msg-box-r{background: #95EC69;max-width: 80%;padding: 8px;border-top-left-radius: 10px;border-bottom-right-radius: 10px;border-bottom-left-radius: 10px;margin-right: 10px;margin-top: 10px;box-shadow: 0 2px 11px -7px rgba(2,66,58,.5)}
  .msg-text-l{color: #000;word-break: break-all;}
  .msg-text-r{color: #000;word-break: break-all;}
.ta{resize: none;width: 100%;height: 100px;position: fixed;bottom: 20px;}
.ta1{resize: none;width: 70%;margin-left:5%;height: 100px;position: fixed;bottom: 20px;}
.r-b{display: flex;align-items: flex-end;flex-direction: column;}
.send-btn{background: #4287FD;color: #fff;padding: 5px 10px;margin: 10px;}
.input-file {
    width: 0.1px; 
    height: 0.1px; 
    opacity: 0; 
    overflow: hidden; 
    position: absolute; 
    z-index: -1;


分别保存为两个html文件,两个都在浏览器打开,页面上出现 “聊天创建成功,您可以开发发送消息了”,则说明连接成功,可以正常发消息了

laravel集成Workerman搭建websocket服务,前端调用,服务器启动插图(4)

至此调试完成!

三、在服务器运行Workerman服务

我们本地调试完成后,最终需要上传到服务器上去运行,例如:Centos,服务上也需要composer安装Workerman,方式和最开头一样,我直接说说如何启动

在服务器上启动Workerman和在本地有一定的区别,因为通常我们希望在服务器上,Websocket能一直处于启动状态,所以,上述所说的启动命令,要稍微改一下,即在命令后加上:–daemonize(守护进程启动)

php artisan Workerman start --daemonize (关掉终端,服务不会停止)

php artisan Workerman stop --daemonize (服务停止)

php artisan Workerman start (关掉终端,服务会停止)

php artisan Workerman stop (服务停止)

至此,laravel集成Workerman搭建websocket服务已完成

 本文参考文章:laravel与workerman结合_laravel workerman-CSDN博客

本站无任何商业行为
个人在线分享 » laravel集成Workerman搭建websocket服务,前端调用,服务器启动
E-->