日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

本篇文章給大家?guī)?lái)了關(guān)于php+socket的相關(guān)知識(shí),其中主要介紹了怎么使用php原生socket實(shí)現(xiàn)一個(gè)簡(jiǎn)易的web聊天室?感興趣的朋友下面一起來(lái)看一下,希望對(duì)大家有幫助。

php原生socket實(shí)現(xiàn)websocket聊天室

前言

這篇文章實(shí)現(xiàn)了使用php原生socket實(shí)現(xiàn)了一個(gè)簡(jiǎn)易的web聊天室,最終代碼在文章最底部。

不出意外的話這應(yīng)該是這個(gè)系列文章的最后一篇了,寫(xiě)這個(gè)系列文章時(shí)本以為是很簡(jiǎn)單的東西,但實(shí)際幾篇寫(xiě)下來(lái)使我?guī)缀跬ㄗx了 workerman 的代碼,所以永遠(yuǎn)不要眼高手低,一定還是要自己嘗試,最好是寫(xiě)出來(lái),才能證明自己真正的弄懂了一件事情

websocket介紹

webSocket 協(xié)議是一種網(wǎng)絡(luò)通信協(xié)議,在 2008 年誕生,2011 年成為國(guó)際標(biāo)準(zhǔn),RFC6455 定義了它的通信標(biāo)準(zhǔn),如今所有瀏覽器都已支持了該協(xié)議。webSocket 是 HTML5 開(kāi)始提供的一種在單個(gè) TCP 連接上進(jìn)行全雙工[^1]通訊的協(xié)議,服務(wù)器可以主動(dòng)向客戶端推送消息,客戶端也可以主動(dòng)向服務(wù)端發(fā)送消息。
webSocket 約定了一個(gè)通信協(xié)議的規(guī)范,通過(guò)握手機(jī)制,客戶端(瀏覽器)和服務(wù)器(webserver)之間能建立一個(gè)類(lèi)似 tcp 的連接,從而方便 cs 通信。

為什么需要websocket

HTTP 協(xié)議是一種無(wú)狀態(tài)的、無(wú)連接的、單向的應(yīng)用層協(xié)議。它采用了 請(qǐng)求 => 響應(yīng) 模型,通信請(qǐng)求僅能由客戶端發(fā)起,服務(wù)端對(duì)請(qǐng)求做出應(yīng)答處理,這種通信模型有一個(gè)弊端:無(wú)法實(shí)現(xiàn)服務(wù)端主動(dòng)向客戶端發(fā)起消息。傳統(tǒng)的 HTTP 請(qǐng)求,其并發(fā)能力都是依賴同時(shí)發(fā)起多個(gè) TCP 連接訪問(wèn)服務(wù)器實(shí)現(xiàn)的而 websocket 則允許我們?cè)谝粭l ws 連接上同時(shí)并發(fā)多個(gè)請(qǐng)求,即在 A 請(qǐng)求發(fā)出后 A 響應(yīng)還未到達(dá),就可以繼續(xù)發(fā)出 B 請(qǐng)求。由于 TCP 的慢啟動(dòng)特性,以及連接本身的握手損耗,都使得 websocket 協(xié)議的這一特性有很大的效率提升。


PHP+Socket系列之實(shí)現(xiàn)websocket聊天室


特點(diǎn)

建立在 TCP 協(xié)議之上,服務(wù)端的實(shí)現(xiàn)相對(duì)比較容易

與 HTTP 協(xié)議有良好的兼容性,默認(rèn)端口也是 80 和 443,并且握手階段采用 HTTP 協(xié)議,因此握手時(shí)不容易被屏蔽,能通過(guò)各種 HTTP 代理服務(wù)器。

數(shù)據(jù)格式比較輕量,性能開(kāi)銷(xiāo)小,通信高效。

可以發(fā)送文本,也可以發(fā)送二進(jìn)制數(shù)據(jù)。

沒(méi)有同源限制,客戶端可以與任意服務(wù)器進(jìn)行通信。

協(xié)議標(biāo)識(shí)符是 ws(如果加密則為 wss),服務(wù)地址就是 URL。


PHP實(shí)現(xiàn)websocket

客戶端與服務(wù)端握手

websocket 協(xié)議在連接前需要握手[^2],通常握手方式有以下幾種方式

基于 flash 的握手協(xié)議(不建議)

基于 md5 加密方式的握手協(xié)議:較早的握手方法,有兩個(gè) key,使用 md5 加密

基于 sha1 加密方式的握手協(xié)議

當(dāng)前主要的握手協(xié)議,本文將以此協(xié)議為主

獲取客戶端上報(bào)的 Sec-WebSocket-key

拼接 key + 258EAFA5-E914-47DA-95CA-C5AB0DC85B11

對(duì)字符串做 SHA1 計(jì)算,再把得到的結(jié)果通過(guò) base64 加密,最后再返回給客戶端

客戶端請(qǐng)求信息如下:

GET /chat HTTP/1.1Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

客戶端需返回如下數(shù)據(jù):

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Sec-WebSocket-Version: 13Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

我們根據(jù)此協(xié)議通過(guò) PHP 方式實(shí)現(xiàn):

<?php
 
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, true);
socket_bind($socket, 0, 8888);
socket_listen($socket);
 
while (true) {
    $conn_sock = socket_accept($socket);
    $request = socket_read($conn_sock, 102400);
 
    $new_key = getShaKey($request);
 
    $response = "HTTP/1.1 101 Switching Protocols\r\n";
    $response .= "Upgrade: websocket\r\n";
    $response .= "Sec-WebSocket-Version: 13\r\n";
    $response .= "Connection: Upgrade\r\n";
    $response .= "Sec-WebSocket-Accept: {$new_key}\r\n\r\n";
 
    socket_write($conn_sock, $response);
}
 
function getShaKey($request)
{
    // 獲取 Sec-WebSocket-key
    preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $request, $match);
 
    // 拼接 key + 258EAFA5-E914-47DA-95CA-C5AB0DC85B11
    $new_key = trim($match[1]) . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
 
    // 對(duì)字符串做 `SHA1` 計(jì)算,再把得到的結(jié)果通過(guò) `base64` 加密
    return base64_encode(sha1($new_key, true));
}

相關(guān)語(yǔ)法解釋可參考 之前的文章,本文章不做詳細(xì)介紹。

使用前端測(cè)試,打開(kāi)我們的任意瀏覽器控制臺(tái)(console)輸入以下內(nèi)容,返回的 websocket 對(duì)象的 readyState 為 1 即為握手成功,此為前端內(nèi)容,本文不多做介紹,詳情可參考 菜鳥(niǎo)教程:

console.log(new WebSocket('ws://192.162.2.166:8888'));
// 運(yùn)行后返回:
WebSocket {
    binaryType: "blob"
    bufferedAmount: 0
    extensions: ""
    onclose: null
    onerror: null
    onmessage: null
    onopen: null
    protocol: ""
    readyState: 1
    url: "ws://192.162.2.166:8888/"
}

發(fā)送數(shù)據(jù)與接收數(shù)據(jù)

使用 websocket 協(xié)議傳輸協(xié)議需要遵循特定的格式規(guī)范,詳情請(qǐng)參考 datatracker.ietf.org/doc/html/rfc6...

PHP+Socket系列之實(shí)現(xiàn)websocket聊天室

為了方便,這里直接貼出加解密代碼,以下代碼借鑒與 workerman 的 src/Protocols/Websocket.php 文件:

// 解碼客戶端發(fā)送的消息
function decode($buffer)
{
    $len = \ord($buffer[1]) & 127;
    if ($len === 126) {
        $masks = \substr($buffer, 4, 4);
        $data = \substr($buffer, 8);
    } else {
        if ($len === 127) {
            $masks = \substr($buffer, 10, 4);
            $data = \substr($buffer, 14);
        } else {
            $masks = \substr($buffer, 2, 4);
            $data = \substr($buffer, 6);
        }
    }
    $dataLength = \strlen($data);
    $masks = \str_repeat($masks, \floor($dataLength / 4)) . \substr($masks, 0, $dataLength % 4);
    return $data ^ $masks;
}
 
// 編碼發(fā)送給客戶端的消息
function encode($buffer)
{
    if (!is_scalar($buffer)) {
        throw new \Exception("You can't send(" . \gettype($buffer) . ") to client, you need to convert it to a string. ");
    }
    $len = \strlen($buffer);
 
    $first_byte = "\x81";
 
    if ($len <= 125) {
        $encode_buffer = $first_byte . \chr($len) . $buffer;
    } else {
        if ($len <= 65535) {
            $encode_buffer = $first_byte . \chr(126) . \pack("n", $len) . $buffer;
        } else {
            $encode_buffer = $first_byte . \chr(127) . \pack("xxxxN", $len) . $buffer;
        }
    }
 
    return $encode_buffer;
}

我們修改剛才 客戶端與服務(wù)端握手 階段的代碼,修改后全代碼全文如下,該段代碼實(shí)現(xiàn)了將客戶端發(fā)送的消息轉(zhuǎn)為大寫(xiě)后返回給客戶端(當(dāng)然只是為了演示):

<?php
 
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, true);
socket_bind($socket, 0, 8888);
socket_listen($socket);
 
while (true) {
    $conn_sock = socket_accept($socket);
    $request = socket_read($conn_sock, 102400);
 
    $new_key = getShaKey($request);
 
    $response = "HTTP/1.1 101 Switching Protocols\r\n";
    $response .= "Upgrade: websocket\r\n";
    $response .= "Sec-WebSocket-Version: 13\r\n";
    $response .= "Connection: Upgrade\r\n";
    $response .= "Sec-WebSocket-Accept: {$new_key}\r\n\r\n";
 
    // 發(fā)送握手?jǐn)?shù)據(jù)
    socket_write($conn_sock, $response);
 
    // 新增內(nèi)容,獲取客戶端發(fā)送的消息并轉(zhuǎn)為大寫(xiě)還給客戶端
    $msg = socket_read($conn_sock, 102400);
    socket_write($conn_sock, encode(strtoupper(decode($msg))));
}
 
function getShaKey($request)
{
    // 獲取 Sec-WebSocket-key
    preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $request, $match);
 
    // 拼接 key + 258EAFA5-E914-47DA-95CA-C5AB0DC85B11
    $new_key = trim($match[1]) . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
 
    // 對(duì)字符串做 `SHA1` 計(jì)算,再把得到的結(jié)果通過(guò) `base64` 加密
    return base64_encode(sha1($new_key, true));
}
 
function decode($buffer)
{
    $len = \ord($buffer[1]) & 127;
    if ($len === 126) {
        $masks = \substr($buffer, 4, 4);
        $data = \substr($buffer, 8);
    } else {
        if ($len === 127) {
            $masks = \substr($buffer, 10, 4);
            $data = \substr($buffer, 14);
        } else {
            $masks = \substr($buffer, 2, 4);
            $data = \substr($buffer, 6);
        }
    }
    $dataLength = \strlen($data);
    $masks = \str_repeat($masks, \floor($dataLength / 4)) . \substr($masks, 0, $dataLength % 4);
    return $data ^ $masks;
}
 
function encode($buffer)
{
    if (!is_scalar($buffer)) {
        throw new \Exception("You can't send(" . \gettype($buffer) . ") to client, you need to convert it to a string. ");
    }
    $len = \strlen($buffer);
 
    $first_byte = "\x81";
 
    if ($len <= 125) {
        $encode_buffer = $first_byte . \chr($len) . $buffer;
    } else {
        if ($len <= 65535) {
            $encode_buffer = $first_byte . \chr(126) . \pack("n", $len) . $buffer;
        } else {
            $encode_buffer = $first_byte . \chr(127) . \pack("xxxxN", $len) . $buffer;
        }
    }
 
    return $encode_buffer;
}

使用 在線測(cè)試工具 進(jìn)行測(cè)試,可以看到消息已經(jīng)可以正常發(fā)送接收,接下來(lái)的文章將繼續(xù)優(yōu)化代碼,實(shí)現(xiàn)簡(jiǎn)易聊天室,敬請(qǐng)關(guān)注:


PHP+Socket系列之實(shí)現(xiàn)websocket聊天室


實(shí)現(xiàn)web聊天室

我們緊接著上文的代碼繼續(xù)優(yōu)化,以實(shí)現(xiàn)簡(jiǎn)易的web聊天室

多路復(fù)用

其實(shí)就是加一下 socket_select() 函數(shù),本文就不寫(xiě)原理與語(yǔ)法了,詳情可參考 之前的文章,以下代碼修改自前文 發(fā)送數(shù)據(jù)與接收數(shù)據(jù)

...
 
socket_listen($socket);
 
+$sockets[] = $socket;
+$user = [];
while (true) {
+   $tmp_sockets = $sockets;
+   socket_select($tmp_sockets, $write, $except, null);
 
+   foreach ($tmp_sockets as $sock) {
+       if ($sock == $socket) {
+           $sockets[] = socket_accept($socket);
+           $user[] = ['socket' => $socket, 'handshake' => false];
+       } else {
+           $curr_user = $user[array_search($sock, $user)];
+           if ($curr_user['handshake']) { // 已握手
+               $msg = socket_read($sock, 102400);
+               echo '客戶端發(fā)來(lái)消息' . decode($msg);
+               socket_write($sock, encode('這是來(lái)自服務(wù)端的消息'));
+           } else {
+               // 握手
+           }
+       }
+   }
 
-   $conn_sock = socket_accept($socket);
-   $request = socket_read($conn_sock, 102400);
 
...


實(shí)現(xiàn)聊天室

最終成果演示


PHP+Socket系列之實(shí)現(xiàn)websocket聊天室


我們將上述代碼改造成類(lèi),并在類(lèi)變量?jī)?chǔ)存用戶信息,添加消息處理等邏輯,最后貼出代碼,建議保存下來(lái)自己嘗試一下,也許會(huì)有全新的認(rèn)知,后端代碼:

<?php
 
new WebSocket();
 
class Websocket
{
    /**
     * @var resource
     */
    protected $socket;
 
    /**
     * @var array 用戶列表
     */
    protected $user = [];
 
    /**
     * @var array 存放所有 socket 資源
     */
    protected $socket_list = [];
 
    public function __construct()
    {
        $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        socket_set_option($this->socket, SOL_SOCKET, SO_REUSEADDR, true);
        socket_bind($this->socket, 0, 8888);
        socket_listen($this->socket);
 
        // 將 socket 資源放入 socket_list
        $this->socket_list[] = $this->socket;
 
        while (true) {
            $tmp_sockets = $this->socket_list;
            socket_select($tmp_sockets, $write, $except, null);
 
            foreach ($tmp_sockets as $sock) {
                if ($sock == $this->socket) {
                    $conn_sock = socket_accept($sock);
                    $this->socket_list[] = $conn_sock;
                    $this->user[] = ['socket' => $conn_sock, 'handshake' => false, 'name' => '無(wú)名氏'];
                } else {
                    $request = socket_read($sock, 102400);
                    $k = $this->getUserIndex($sock);
 
                    if (!$request) {
                        continue;
                    }
 
                    // 用戶端斷開(kāi)連接
                    if ((\ord($request[0]) & 0xf) == 0x8) {
                        $this->close($k);
                        continue;
                    }
 
                    if (!$this->user[$k]['handshake']) {
                        // 握手
                        $this->handshake($k, $request);
                    } else {
                        // 已握手
                        $this->send($k, $request);
                    }
                }
            }
        }
    }
 
    /**
     * 關(guān)閉連接
     *
     * @param $k
     */
    protected function close($k)
    {
        $u_name = $this->user[$k]['name'] ?? '無(wú)名氏';
        socket_close($this->user[$k]['socket']);
        $socket_key = array_search($this->user[$k]['socket'], $this->socket_list);
        unset($this->socket_list[$socket_key]);
        unset($this->user[$k]);
 
        $user = [];
        foreach ($this->user as $v) {
            $user[] = $v['name'];
        }
        $res = [
            'type' => 'close',
            'users' => $user,
            'msg' => $u_name . '已退出',
            'time' => date('Y-m-d H:i:s')
        ];
        $this->sendAllUser($res);
    }
 
    /**
     * 獲取用戶索引
     *
     * @param $socket
     * @return int|string
     */
    protected function getUserIndex($socket)
    {
        foreach ($this->user as $k => $v) {
            if ($v['socket'] == $socket) {
                return $k;
            }
        }
    }
 
    /**
     * 握手
     * @param $k
     * @param $request
     */
    protected function handshake($k, $request)
    {
        preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $request, $match);
        $key = base64_encode(sha1($match[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));
 
        $response = "HTTP/1.1 101 Switching Protocols\r\n";
        $response .= "Upgrade: websocket\r\n";
        $response .= "Connection: Upgrade\r\n";
        $response .= "Sec-WebSocket-Accept: {$key}\r\n\r\n";
        socket_write($this->user[$k]['socket'], $response);
        $this->user[$k]['handshake'] = true;
    }
 
    /**
     * 接收并處理消息
     *
     * @param $k
     * @param $msg
     */
    public function send($k, $msg)
    {
        $msg = $this->decode($msg);
        $msg = json_decode($msg, true);
 
        if (!isset($msg['type'])) {
            return;
        }
 
        switch ($msg['type']) {
            case 'login': // 登錄
                $this->user[$k]['name'] = $msg['name'] ?? '無(wú)名氏';
                $users = [];
                foreach ($this->user as $v) {
                    $users[] = $v['name'];
                }
                $res = [
                    'type' => 'login',
                    'name' => $this->user[$k]['name'],
                    'msg' => $this->user[$k]['name'] . ': login success',
                    'users' => $users,
                ];
                $this->sendAllUser($res);
                break;
            case 'message': // 接收并發(fā)送消息
                $res = [
                    'type' => 'message',
                    'name' => $this->user[$k]['name'] ?? '無(wú)名氏',
                    'msg' => $msg['msg'],
                    'time' => date('H:i:s'),
                ];
                $this->sendAllUser($res);
                break;
        }
    }
 
    /**
     * 發(fā)送給所有人
     *
     */
    protected function sendAllUser($msg)
    {
        if (is_array($msg)) {
            $msg = json_encode($msg);
        }
 
        $msg = $this->encode($msg);
 
        foreach ($this->user as $k => $v) {
            socket_write($v['socket'], $msg, strlen($msg));
        }
    }
 
    /**
     * 解碼
     *
     * @param $buffer
     * @return string
     */
    protected function decode($buffer)
    {
        $len = \ord($buffer[1]) & 127;
        if ($len === 126) {
            $masks = \substr($buffer, 4, 4);
            $data = \substr($buffer, 8);
        } else {
            if ($len === 127) {
                $masks = \substr($buffer, 10, 4);
                $data = \substr($buffer, 14);
            } else {
                $masks = \substr($buffer, 2, 4);
                $data = \substr($buffer, 6);
            }
        }
        $dataLength = \strlen($data);
        $masks = \str_repeat($masks, \floor($dataLength / 4)) . \substr($masks, 0, $dataLength % 4);
        return $data ^ $masks;
    }
 
    protected function encode($buffer)
    {
        if (!is_scalar($buffer)) {
            throw new \Exception("You can't send(" . \gettype($buffer) . ") to client, you need to convert it to a string. ");
        }
        $len = \strlen($buffer);
 
        $first_byte = "\x81";
 
        if ($len <= 125) {
            $encode_buffer = $first_byte . \chr($len) . $buffer;
        } else {
            if ($len <= 65535) {
                $encode_buffer = $first_byte . \chr(126) . \pack("n", $len) . $buffer;
            } else {
                $encode_buffer = $first_byte . \chr(127) . \pack("xxxxN", $len) . $buffer;
            }
        }
 
        return $encode_buffer;
    }
}

前端代碼如下(前端內(nèi)容不在本文討論范圍之內(nèi),具體可參考 菜鳥(niǎo)教程):

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<style>
    * {
        margin: 0;
        padding: 0;
    }
    h3 {
        display: flex;
        justify-content: center;
        margin: 30px auto;
    }
    .but-box {
        border-radius: 5px;
        display: flex;
        justify-content: center;
        align-items: center;
        margin-top: 10px;
    }
    #box {
        display: flex;
        margin: 5px auto;
        border-radius: 5px;
        border: 1px #ccc solid;
        height: 400px;
        width: 700px;
        overflow-y: auto;
        overflow-x: hidden;
        position: relative;
    }
    #msg-box {
        width: 480px;
        margin-right: 111px;
        height: 100%;
        overflow-y: auto;
        overflow-x: hidden;
    }
    #user-box {
        width: 110px;
        overflow-y: auto;
        overflow-x: hidden;
        float: left;
        border-left: 1px #ccc solid;
        height: 100%;
        background-color: #F1F1F1;
    }
    button {
        float: right;
        width: 80px;
        height: 35px;
        font-size: 18px;
    }
    input {
        width: 100%;
        height: 30px;
        padding: 2px;
        line-height: 20px;
        outline: none;
        border: solid 1px #CCC;
    }
    .but-box p {
        margin-right: 160px;
    }
</style>
<body>
 
<h3>這是一個(gè)php socket實(shí)現(xiàn)的web聊天室</h3>
 
<div id="box">
    <div id="msg-box"></div>
    <div id="user-box"></div>
</div>
 
<div>
 
    <p><textarea cols="60" rows="3" style="resize:none;pedding: 10px"    id="content"> </textarea></p>
    <button id="send">發(fā)送</button>
</div>
<script src="https://cdn.bootcss.com/jquery/2.2.1/jquery.min.js"></script>
<script>
    let ws = new WebSocket('ws://124.222.85.67:8888');
 
    ws.onopen = function (event) {
        console.log('連接成功');
 
        var name = prompt('請(qǐng)輸入用戶名:');
 
        ws.send(JSON.stringify({
            type: 'login',
            name: name
        }));
 
        if (!name) {
            alert('好你個(gè)壞蛋,竟然沒(méi)有輸入用戶名');
        }
    };
    ws.onmessage = function (event) {
        let data = JSON.parse(event.data);
        console.log(data);
 
        switch (data.type) {
            case 'close':
            case 'login':
                $("#user-box").html('');
                data.users.forEach(function (item) {
                    $("#user-box").append(`<p style="color: grey;">${item}</p>`);
                });
                if (data.msg) {
                    $("#msg-box").append(`<p style="color: grey;">${data.msg}</p>`);
                }
                break;
            case 'message':
                $("#msg-box").append(`<p><span style="color: #0A89FF">${data.time}</span><span style="color: red">${data.name}</span>${data.msg}</p>`);
                break;
        }
    };
 
    ws.onclose = function (event) {
        alert('連接關(guān)閉');
    };
 
    document.onkeydown = function (event) {
        if (event.keyCode == 13) {
            send();
        }
    }
 
    $("#send").click(function () {
        send();
    });
 
    function send() {
        let content = $("#content").val();
        $("#content").val('');
        if (!content) {
            return;
        }
        ws.send(JSON.stringify({
            type: 'message',
            msg: content
        }));
    }
</script>
</body>
</html>

1、是通訊傳輸?shù)囊粋€(gè)術(shù)語(yǔ)。 通信允許數(shù)據(jù)在兩個(gè)方向上同時(shí)傳輸,它在能力上相當(dāng)于兩個(gè)單工通信方式的結(jié)合

2、為了建立 websocket 連接,需要通過(guò)瀏覽器發(fā)出請(qǐng)求,之后服務(wù)器進(jìn)行回應(yīng),這個(gè)過(guò)程通常稱為“握手”(Handshaking)


分享到:
標(biāo)簽:PHP+Socket聊天室 websocket聊天室
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定