swoole和websocket简单聊天室_swoole和websocket简单聊天室开发

更新时间:2024-03-14    来源:班主任工作日志    手机版     字体:

【www.bbyears.com--班主任工作日志】

首先,我想说下写代码的一些习惯,第一,任何可配置的参数或变量都要写到一个config文件中。第二,代码中一定要有日志记录和完善的报错并记录报错。言归正传,swoole应该是每个phper必须要了解的,它号称重新定义了php。此聊天室利用了swoole高并发并且异步非阻塞的特点提高了程序的性能。

首先,定义一个 swoole_lock swoole_websocket_server ,并且配置参数,具体参数详情可以去swoole官网查看。

public function start()
{
   $this->lock = new swoole_lock(SWOOLE_MUTEX);            

   // 对文件或数组进行锁操作,已达到同步
   $this->server = new swoole_websocket_server($this->addr, $this->port);  

   // swoole提供的Websocket Server
   $this->server->set(array(
      "daemonize" => 0,
      "worker_num" => 4,
      "task_worker_num" => 10,
      "max_request" => 1000,
      "log_file" => ROOT_PATH . "storage\\logs\\swoole.log"   

    // swoole日志路径,必须是绝对路径
   ));

   $this->server->on("open", array($this, "onOpen"));
   $this->server->on("message", array($this, "onMessage"));
   $this->server->on("task", array($this, "onTask"));
   $this->server->on("finish", array($this, "onFinish"));
   $this->server->on("close", array($this, "onClose"));

   // 启动服务
   $this->server->start();
}

当有客户端链接时,简单记录客户端的信息。

public function onOpen($server, $request)
    {
      $message = array(
        "remote_addr" => $request->server["remote_addr"],
        "request_time" => date("Y-m-d H:i:s", $request->server["request_time"])
      );
      write_log($message);
    }

当有客户端发送信息时,对信息进行处理。

public function onMessage($server, $frame)
    {
      $data = json_decode($frame->data);

      switch ($data->type) {
        case "init":
        case "INIT":
          $this->users[$frame->fd] = $data->message;  、

      // 记录每个链接的信息,同样不要尝试打印出来看,因为你只能看到自己的链接信息
          $message = "欢迎" . $data->message . "加入了聊天室";
          $response = array(
            "type" => 1,  // 1代表系统消息,2代表用户聊天
            "message" => $message
          );
          break;
        case "chat":
        case "CHAT":
          $message = $data->message;
          $response = array(
            "type" => 2,  // 1代表系统消息,2代表用户聊天
            "username" => $this->users[$frame->fd],
            "message" => $message
          );
          break;
        default:
          return false;
      }
        
       // 将信息交给task处理
      $this->server->task($response);
    }

    public function onTask($server, $task_id, $from_id, $message)
    {
       // 迭代所有的客户端链接,将消息推送过去。(如果你尝试将 $this->server->connections 打印出来,那么你会发现他是空的。但当时用 foreach 去循环时,它确实有用。)
      foreach ($this->server->connections as $fd) {
        $this->server->push($fd, json_encode($message));
      }
      $server->finish( "Task" . $task_id . "Finished" . PHP_EOL);
    }

最后,当客户端断开链接时,利用锁机制,同步删除客户端信息,并记录日志。

public function onClose($server, $fd)
    {
      $username = $this->users[$fd];
      // 释放客户端,利用锁进行同步
      $this->lock->lock();
      unset($this->users[$fd]);
      $this->lock->unlock();

      if( $username ) {
        $response = array(
          "type" => 1,  // 1代表系统消息,2代表用户聊天
          "message" => $username . "离开了聊天室"
        );
        $this->server->task($response);
      }


      write_log( $fd . " disconnected");
    }

服务端完了,下面就是客户端,很简单,只需要用websocket链接就ok!

// websocket
    let address = "ws://";
    let webSocket = new WebSocket(address);
    webSocket.onerror = function (event) {
      alert("服务器连接错误,请稍后重试");
    };
    webSocket.onopen = function (event) {
      if(!sessionStorage.getItem("username")) {
        setName();
      }else {
        username = sessionStorage.getItem("username")
        webSocket.send(JSON.stringify({
          "message": username,
          "type": "init"
        }));
      }
    };
    webSocket.onmessage = function (event) {
      console.log(event);
      let data = JSON.parse(event.data);
      if (data.type == 1) {
        $("#chat-list2").append("
  • 系统消息:" + data.message + ""); } else if (data.type == 2) { $("#chat-list2").append("
  • " + data.username + ":" + data.message + ""); } }; webSocket.onclose = function (event) { alert("散了吧,服务器都关了"); };
  • 详细代码可以去我的github下载

    本文来源:http://www.bbyears.com/banzhurengongzuo/142039.html

    热门标签

    更多>>

    本类排行