WebSocket使用筆記

來源:互聯網
上載者:User
一、簡介

對於網頁中快速的發送接收多條訊息,WebSocket非常適合來解決這種需求。此次使用WebSocket來搭建一個聊天網頁應用。主要涉及的用戶端的實現,服務端使用是一個php來實現的WebSocket服務端,在本篇中暫不做詳細介紹。
主要的JavaScript代碼有這些

  • new WebSocket 建立一個websocket對象
  • socket.onopen 建立串連後觸發
  • socket.onerror 錯誤時觸發
  • socket.onmessage 接受到資料時觸發
  • socket.onclose 串連關閉時觸發
  • socket.send() 發送資料

二、成果

最終實現的是向伺服器發訊息,伺服器返回相同訊息,效果如所示。線上展示版點擊圖片下發連結

線上版本在這裡

三、代碼

JavaScript

var socket;var submit = document.getElementById('submit');//首先輸入聊天者名字,提交後可開始聊天var button = document.getElementById('send');//發送按鈕button.addEventListener('click', sendMsg);submit.addEventListener('click', startChat);functionstartChat(){    document.getElementById('modal').style.visibility = "collapse";    document.getElementById('modalBody').style.visibility = "collapse";    connect();//串連伺服器}//發送訊息functionsendMsg(){var txetArea = document.getElementById('sendText');    var content = txetArea.value;    var client = document.getElementById('name').value;    showMsg(content,0);    txetArea.value = "";    msg = {        name: client,        message: content    }    socket.send(JSON.stringify(msg)); //發送資料}//顯示訊息functionshowMsg(content,type){var mainDiv = document.getElementById('main');    var div = document.createElement('div');    mainDiv.appendChild(div);    var lineDiv = mainDiv.lastChild;    lineDiv.className = 'line';    lineDiv.innerHTML = (function(){if (type == 0){            return"";        }        else {            return"";        }    })();    var contentDiv = lineDiv.lastChild;    contentDiv.innerHTML = content;    mainDiv.scrollTop = mainDiv.scrollHeight - mainDiv.clientHeight;}//建立串連functionconnect(){var http_request;    if (window.XMLHttpRequest){          http_request = new XMLHttpRequest();         if (http_request.overrideMimeType){            http_request.overrideMimeType('text/xml');         }    } elseif (window.ActiveXObject) {         try {            http_request = new ActiveXObject("Msxml2.XMLHTTP");        } catch (e){            try {                http_request = new ActiveXObject("Microsoft.XMLHTTP");            } catch (e){}        }    }    http_request.open('GET', "http://localhost/websocket/server.php", true);    http_request.send();    socket = new WebSocket("ws://localhost:9000/websocket/server.php");    socket.onopen = open; //綁定成功開啟後觸發的函數    socket.onmessage = recMessage; //綁定接受到資料後的處理函數    socket.onerror = error; //綁定處理錯誤的函數    socket.onclose = close; //綁定串連關閉後的處理函數}//串連成功functionopen(){var i = document.getElementsByTagName('i');    i[0].innerHTML = '串連成功!';    button.disabled = '';}//出錯functionerror(){var i = document.getElementsByTagName('i');    i[0].style.color = "#FF0000";    i[0].innerHTML = '串連失敗';    button.disabled = 'disabled';}//接受到資料functionrecMessage(e){var data = JSON.parse(e.data);    showMsg(data.message, 1);}//串連關閉functionclose(){    button.disabled = 'disabled';    if (confirm('串連已關閉,是否需要再次串連?')){        connect();    }}

php服務端代碼,已封裝成類

namespaceMyLab;classWebSocket{private$host;    private$port;    function__construct($port, $host)    {$this->host = $host;        $this->port = $port;    }    //啟動服務functionStartServer(){$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);//建立socket        socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);        socket_bind($socket, 0, $this->port);        socket_listen($socket);//開啟監聽$sockets = array($socket);        $write = NULL;        $except = NULL;        while (true)        {            $clients = $sockets;            $num = socket_select($clients, $write, $except, 0);            if ($num === false){                echo"socket_select failed!";                break;            }            if (in_array($socket, $clients))            {                $socket_new = socket_accept($socket); //接受串連$sockets[] = $socket_new; //儲存串連$header =  socket_read($socket_new, 1024);                $status = $this->handshaking($header, $socket_new, $this->host, $this->port);                $response = $this->code(json_encode(array('message'=>'歡迎來到Chat with yourself')));                $status = $this->sendMessage($response, $socket_new);//首次串連上之後回應$found_socket = array_search($socket, $clients);                unset($clients[$found_socket]);            }            foreach ($clientsas$client) //遍曆串連,處理接受到的訊息            {                while (socket_recv($client, $buf, 1024, 0) >= 1)                {                    $received_text = $this->decode($buf);                    $decode_text = json_decode($received_text);                    $user_name = $decode_text->name;                    $user_message = $decode_text->message;                    $response_text = $this->code(json_encode(array('type' => 'usermsg', 'name' => $user_name, 'message' => $user_message)));                    $this->sendMessage($response_text, $client);                    break2;                }            }        }    }    //握手驗證functionhandshaking($receved_header,$client_conn, $host, $port)    {$headers = array();        $lines = preg_split("/\r\n/", $receved_header);        foreach($linesas$line)        {            $line = chop($line);            if(preg_match('/\A(\S+): (.*)\z/', $line, $matches))            {                $headers[$matches[1]] = $matches[2];            }        }        $secKey = $headers['Sec-WebSocket-Key'];        $secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));        $upgrade  = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .        "Upgrade: websocket\r\n" .        "Connection: Upgrade\r\n" .        "WebSocket-Origin: $host\r\n" .        "WebSocket-Location: ws://$host:$port/demo/shout.php\r\n".        "Sec-WebSocket-Accept:$secAccept\r\n\r\n";        socket_write($client_conn,$upgrade,strlen($upgrade));        return$upgrade;    }    //解碼functiondecode($str)    {$length = ord($str[1]) & 127;        if ($length == 126)        {            $masks = substr($str, 4, 4);            $data = substr($str, 8);        }        elseif ($length == 127) {            $masks = substr($str, 10, 4);            $data = substr($str, 14);        }        else {            $masks = substr($str, 2, 4);            $data = substr($str, 6);        }        $str = '';        for ($i = 0; $i < strlen($data); ++$i)        {            $str .= $data[$i] ^ $masks[$i % 4];        }        return$str;    }    //發送訊息functionsendMessage($msg, $cilent)    {try{            return socket_write($cilent, $msg, strlen($msg));        }        catch (\Exception$e){            return$e;        }    }    //編碼functioncode($str)    {$b1 = 0x80 | (0x1 & 0x0f);        $length = strlen($str);        if ($length <= 125)            $header = pack('CC', $b1, $length);        elseif ($length >125 && $length < 65536)            $header = pack('CCn', $b1, 126, $length);        elseif ($length >= 65536)            $header = pack('CCNN', $b1, 127, $length);        else {            returnfalse;        }        return$header.$str;    }}

').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('
  • ').text(i)); }; $numbering.fadeIn(1700); }); });

    以上就介紹了WebSocket使用筆記,包括了方面的內容,希望對PHP教程有興趣的朋友有所協助。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.