workerman 使用服务端和客户端 SSL证书版

服务端安装

composer require workerman/workerman

客户端安装

composer require textalk/websocket

服务器端

ssl证书是按域名申请的

<?php

namespace App\Controllers;

use Workerman\Worker;
use Workerman\Lib\Timer;
use WebSocket\Client;
class Workerman extends BaseController
{
     protected $uidConnections = [];
    protected $HEARTBEAT_TIME = '60';
    public $code_arr = [
        '100' => ['code'=>100, 'msg'=>'连接成功'],
        '101' => ['code'=>101, 'msg'=>'登录成功'],
        '102' => ['code'=>102, 'msg'=>'发送数据'],
        '103' => ['code'=>103, 'msg'=>'接收成功'],
        '131' => ['code'=>131, 'msg'=>'发送失败'],
        ];
    protected $worker = null;
    public $count = 0;

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'workerman:websocket';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * 
     * @var string
     */
    protected $redis = '';
    /**
     * SSL证书路径
     * @var string
     */
    protected $http_psth = '/usr/local/nginx/conf/cert/';
    /**
     * The console command description.
     *
     * @var string
     */
    protected $redisname = 'long:';
    /**
     * Create a new command instance.
     *
     * @return void
     */

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $this->start();
    }

    public function start()
    {
          $context = array(
              // 更多ssl选项请参考手册 http://php.net/manual/zh/context.ssl.php
              'ssl' => array(
                  // 请使用绝对路径
                  'local_cert'        => $this->http_psth.'域名.pem', // 也可以是crt文件
                  'local_pk'          => $this->http_psth.'域名.key',
                  'verify_peer'       => false,
                  'allow_self_signed' => true, //如果是自签名证书需要开启此选项
              )
          );
          $this->worker = new Worker('websocket://0.0.0.0:1818', $context);
          $this->worker->transport = 'ssl';
          $this->onConnect();
          $this->onMessage();
          $this->onClose();
          $this->redis = $this->redisdb();
        

          Worker::runAll();
    }

    public function onConnect() {
        $this->worker->onConnect = function($connection) {
            $connection->send(json_encode($this->code_arr['100']));
            $this->count++;
            $msg = "新的连接 目前连接数 {$this->count}";
            var_dump($msg);
            log_message('error',$msg);
        };
    }

    public function onMessage() {
        $this->worker->onMessage = function ($connection, $data){
          log_message('error','sssss:'.$data);
            $connection->lastMessageTime = time();  //更新上一次会话时间
            
            //客户端心跳 直接返回
            if ($data == "") {
                return;
            }
            $data = json_decode($data, true);
            $uid = $uid = $data['uid'];
            
            if (empty($uid)) {
                $connection->close();
                return;
            }

            log_message('error','uid:'.$uid);
            switch ($data['type']) {
                case 'login':
                    // 保存该用户的输送数据
                    $connection->uid = $uid;
                    $this->uidConnections[$uid] = $connection;
                    $msg = "uid:{$uid} 登录成功 目前登录数".count($this->uidConnections);

                    $send_data = $this->code_arr['101'];
                    // $send_data['info'] = $notify;
                    log_message('error',$msg);
                    $connection->send(json_encode($send_data));
                    break;
                case 'send':
                    // 发送消息
                    $res = $this->sendMessageByUid($uid);
                    $msg = "发送成功";
                    if (!$res) {
                        $msg = "发送失败";
                    }
                    // var_dump($msg);
                    log_message('error',$msg);
                    break;
                case 'message':
                    break;
            }
        };
    }

    // 针对uid推送数据
    public function sendMessageByUid($uid)
    {
         if(isset($this->uidConnections[$uid]))
         {
               $notify = $this->redis->get($this->redisname.$uid);
               if($notify){
                    $this->redis->delete($this->redisname.$uid);
                    $notify = unserialize($notify);
               }
               $send_data = $this->code_arr['102'];
               $send_data['info'] = $notify;
               $this->uidConnections[$uid]->send(json_encode($send_data));
               return true;
         }
         return false;
    }
     public function onClose() {
        $this->worker->onClose = function ($connection){
            $this->count--;
            if(isset($connection->uid)) {
                $msg = "uid:{$connection->uid} 已断开";
                var_dump($msg);
            log_message('error',$msg);
                unset($this->uidConnections[$connection->uid]);
            }
            $msg = "连接已断开 目前连接数 {$this->count}";
            var_dump($msg);
            log_message('error',$msg);
            // Log::write("$msg", 'WorkerManServer');
        };
     }
     public function redisdb($db=0)
     {
         $redis=new \redis();
         $redis->connect(env("redis.default.host"),env("redis.default.port"));
         $redis->select(env("redis.default.db"));
         return $redis;
     }


}
?>

服务器上的 客户端

public function test($data='')
     {
          $data = array(
               'uid' => 1,
               'type' => 'send',
               'info' => ['sss1'=>11]
          );
          $json = json_encode($data);
          $client = new Client("wss://域名:1818");
          $client->send($json);
          $data1 = array(
               'uid' => 2,
               'type' => 'send',
               'info' => ['sss2'=>11]
          );
          $json = json_encode($data1);
          $client->send($json);
          $message = $client->receive();
          log_message('error',$message);
          $client->close();//WebSocket\
     }

前端js代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div style="margin: 0 auto;width: 800px">
    <h2>聊天室</h2>
    <textarea type="text" style="border: 1px solid black;width: 800px;height: 200px;" id="his"></textarea>
    <input type="text" style="width:740px" id="sendMsg">&nbsp;<button id="send">发送</button>
</div>
</body>
</html>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
 
    $(function () {
        var ws = new WebSocket("wss://域名:1818");

       $('#send').click(function () {
           msg = $('#sendMsg').val();
           $('#sendMsg').val('');
           ws.send(msg);
       });
        ws.onopen = function() {
            $('#his').append("服务器连接成功.....");
            $('#his').append("\n");
        };
        ws.onmessage = function(e) {
            $('#his').append(e.data);
            $('#his').append("\n");
        };
 
    });
</script>

参考无证书版本:

workerman 使用服务端和客户端-CSDN博客

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值