Home >Backend Development >PHP Tutorial >WebSocket usage notes
1. Introduction
For quickly sending and receiving multiple messages on web pages, WebSocket is very suitable to solve this need. This time, WebSocket is used to build a chat web application. It mainly involves the implementation of the client. The server uses a WebSocket server implemented in PHP. I will not introduce it in detail in this article.
The main JavaScript code is as follows
2. Results
What is finally achieved is to send a message to the server, and the server returns the same message. The effect is as shown in the figure below. Click on the picture to send the link to the online display version
The online version is here
3. Code
JavaScript
<code><span>var</span> socket; <span>var</span> submit = document.getElementById(<span>'submit'</span>);<span>//首先输入聊天者名字,提交后可开始聊天</span><span>var</span> button = document.getElementById(<span>'send'</span>);<span>//发送按钮</span> button.addEventListener(<span>'click'</span>, sendMsg); submit.addEventListener(<span>'click'</span>, startChat); <span><span>function</span><span>startChat</span><span>()</span>{</span> document.getElementById(<span>'modal'</span>).style.visibility = <span>"collapse"</span>; document.getElementById(<span>'modalBody'</span>).style.visibility = <span>"collapse"</span>; connect();<span>//连接服务器</span> } <span>//发送消息</span><span><span>function</span><span>sendMsg</span><span>()</span>{</span><span>var</span> txetArea = document.getElementById(<span>'sendText'</span>); <span>var</span> content = txetArea.value; <span>var</span> client = document.getElementById(<span>'name'</span>).value; showMsg(content,<span>0</span>); txetArea.value = <span>""</span>; msg = { name: client, message: content } socket.send(<span>JSON</span>.stringify(msg)); <span>//发送数据</span> } <span>//显示消息</span><span><span>function</span><span>showMsg</span><span>(content,type)</span>{</span><span>var</span> mainDiv = document.getElementById(<span>'main'</span>); <span>var</span> div = document.createElement(<span>'div'</span>); mainDiv.appendChild(div); <span>var</span> lineDiv = mainDiv.lastChild; lineDiv.className = <span>'line'</span>; lineDiv.innerHTML = (<span><span>function</span><span>()</span>{</span><span>if</span> (type == <span>0</span>){ <span>return</span><span>"<div class='\"selfContent\"'></div>"</span>; } <span>else</span> { <span>return</span><span>"<div class='\"content\"'></div>"</span>; } })(); <span>var</span> contentDiv = lineDiv.lastChild; contentDiv.innerHTML = content; mainDiv.scrollTop = mainDiv.scrollHeight - mainDiv.clientHeight; } <span>//建立连接</span><span><span>function</span><span>connect</span><span>()</span>{</span><span>var</span> http_request; <span>if</span> (window.XMLHttpRequest){ http_request = <span>new</span> XMLHttpRequest(); <span>if</span> (http_request.overrideMimeType){ http_request.overrideMimeType(<span>'text/xml'</span>); } } <span>else</span><span>if</span> (window.ActiveXObject) { <span>try</span> { http_request = <span>new</span> ActiveXObject(<span>"Msxml2.XMLHTTP"</span>); } <span>catch</span> (e){ <span>try</span> { http_request = <span>new</span> ActiveXObject(<span>"Microsoft.XMLHTTP"</span>); } <span>catch</span> (e){} } } http_request.open(<span>'GET'</span>, <span>"http://localhost/websocket/server.php"</span>, <span>true</span>); http_request.send(); socket = <span>new</span> WebSocket(<span>"ws://localhost:9000/websocket/server.php"</span>); socket.onopen = open; <span>//绑定成功打开后触发的函数</span> socket.onmessage = recMessage; <span>//绑定接受到数据后的处理函数</span> socket.onerror = error; <span>//绑定处理错误的函数</span> socket.onclose = close; <span>//绑定连接关闭后的处理函数</span> } <span>//连接成功</span><span><span>function</span><span>open</span><span>()</span>{</span><span>var</span> i = document.getElementsByTagName(<span>'i'</span>); i[<span>0</span>].innerHTML = <span>'连接成功!'</span>; button.disabled = <span>''</span>; } <span>//出错</span><span><span>function</span><span>error</span><span>()</span>{</span><span>var</span> i = document.getElementsByTagName(<span>'i'</span>); i[<span>0</span>].style.color = <span>"#FF0000"</span>; i[<span>0</span>].innerHTML = <span>'连接失败'</span>; button.disabled = <span>'disabled'</span>; } <span>//接受到数据</span><span><span>function</span><span>recMessage</span><span>(e)</span>{</span><span>var</span> data = <span>JSON</span>.parse(e.data); showMsg(data.message, <span>1</span>); } <span>//连接关闭</span><span><span>function</span><span>close</span><span>()</span>{</span> button.disabled = <span>'disabled'</span>; <span>if</span> (confirm(<span>'连接已关闭,是否需要再次连接?'</span>)){ connect(); } }</code>
php server code, which has been encapsulated into a class
<code><span><span><?php </span><span>namespace</span><span>MyLab</span>; <span><span>class</span><span>WebSocket</span>{</span><span>private</span><span>$host</span>; <span>private</span><span>$port</span>; <span><span>function</span><span>__construct</span><span>(<span>$port</span>, <span>$host</span>)</span> {</span><span>$this</span>->host = <span>$host</span>; <span>$this</span>->port = <span>$port</span>; } <span>//启动服务</span><span><span>function</span><span>StartServer</span><span>()</span>{</span><span>$socket</span> = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);<span>//创建socket</span> socket_set_option(<span>$socket</span>, SOL_SOCKET, SO_REUSEADDR, <span>1</span>); socket_bind(<span>$socket</span>, <span>0</span>, <span>$this</span>->port); socket_listen(<span>$socket</span>);<span>//开启监听</span><span>$sockets</span> = <span>array</span>(<span>$socket</span>); <span>$write</span> = <span>NULL</span>; <span>$except</span> = <span>NULL</span>; <span>while</span> (<span>true</span>) { <span>$clients</span> = <span>$sockets</span>; <span>$num</span> = socket_select(<span>$clients</span>, <span>$write</span>, <span>$except</span>, <span>0</span>); <span>if</span> (<span>$num</span> === <span>false</span>){ <span>echo</span><span>"socket_select failed!"</span>; <span>break</span>; } <span>if</span> (in_array(<span>$socket</span>, <span>$clients</span>)) { <span>$socket_new</span> = socket_accept(<span>$socket</span>); <span>//接受连接</span><span>$sockets</span>[] = <span>$socket_new</span>; <span>//保存连接</span><span>$header</span> = socket_read(<span>$socket_new</span>, <span>1024</span>); <span>$status</span> = <span>$this</span>->handshaking(<span>$header</span>, <span>$socket_new</span>, <span>$this</span>->host, <span>$this</span>->port); <span>$response</span> = <span>$this</span>->code(json_encode(<span>array</span>(<span>'message'</span>=><span>'欢迎来到Chat with yourself'</span>))); <span>$status</span> = <span>$this</span>->sendMessage(<span>$response</span>, <span>$socket_new</span>);<span>//首次连接上之后回应</span><span>$found_socket</span> = array_search(<span>$socket</span>, <span>$clients</span>); <span>unset</span>(<span>$clients</span>[<span>$found_socket</span>]); } <span>foreach</span> (<span>$clients</span><span>as</span><span>$client</span>) <span>//遍历连接,处理接受到的消息</span> { <span>while</span> (socket_recv(<span>$client</span>, <span>$buf</span>, <span>1024</span>, <span>0</span>) >= <span>1</span>) { <span>$received_text</span> = <span>$this</span>->decode(<span>$buf</span>); <span>$decode_text</span> = json_decode(<span>$received_text</span>); <span>$user_name</span> = <span>$decode_text</span>->name; <span>$user_message</span> = <span>$decode_text</span>->message; <span>$response_text</span> = <span>$this</span>->code(json_encode(<span>array</span>(<span>'type'</span> => <span>'usermsg'</span>, <span>'name'</span> => <span>$user_name</span>, <span>'message'</span> => <span>$user_message</span>))); <span>$this</span>->sendMessage(<span>$response_text</span>, <span>$client</span>); <span>break</span><span>2</span>; } } } } <span>//握手验证</span><span><span>function</span><span>handshaking</span><span>(<span>$receved_header</span>,<span>$client_conn</span>, <span>$host</span>, <span>$port</span>)</span> {</span><span>$headers</span> = <span>array</span>(); <span>$lines</span> = preg_split(<span>"/\r\n/"</span>, <span>$receved_header</span>); <span>foreach</span>(<span>$lines</span><span>as</span><span>$line</span>) { <span>$line</span> = chop(<span>$line</span>); <span>if</span>(preg_match(<span>'/\A(\S+): (.*)\z/'</span>, <span>$line</span>, <span>$matches</span>)) { <span>$headers</span>[<span>$matches</span>[<span>1</span>]] = <span>$matches</span>[<span>2</span>]; } } <span>$secKey</span> = <span>$headers</span>[<span>'Sec-WebSocket-Key'</span>]; <span>$secAccept</span> = base64_encode(pack(<span>'H*'</span>, sha1(<span>$secKey</span> . <span>'258EAFA5-E914-47DA-95CA-C5AB0DC85B11'</span>))); <span>$upgrade</span> = <span>"HTTP/1.1 101 Web Socket Protocol Handshake\r\n"</span> . <span>"Upgrade: websocket\r\n"</span> . <span>"Connection: Upgrade\r\n"</span> . <span>"WebSocket-Origin: $host\r\n"</span> . <span>"WebSocket-Location: ws://$host:$port/demo/shout.php\r\n"</span>. <span>"Sec-WebSocket-Accept:$secAccept\r\n\r\n"</span>; socket_write(<span>$client_conn</span>,<span>$upgrade</span>,strlen(<span>$upgrade</span>)); <span>return</span><span>$upgrade</span>; } <span>//解码</span><span><span>function</span><span>decode</span><span>(<span>$str</span>)</span> {</span><span>$length</span> = ord(<span>$str</span>[<span>1</span>]) & <span>127</span>; <span>if</span> (<span>$length</span> == <span>126</span>) { <span>$masks</span> = substr(<span>$str</span>, <span>4</span>, <span>4</span>); <span>$data</span> = substr(<span>$str</span>, <span>8</span>); } <span>elseif</span> (<span>$length</span> == <span>127</span>) { <span>$masks</span> = substr(<span>$str</span>, <span>10</span>, <span>4</span>); <span>$data</span> = substr(<span>$str</span>, <span>14</span>); } <span>else</span> { <span>$masks</span> = substr(<span>$str</span>, <span>2</span>, <span>4</span>); <span>$data</span> = substr(<span>$str</span>, <span>6</span>); } <span>$str</span> = <span>''</span>; <span>for</span> (<span>$i</span> = <span>0</span>; <span>$i</span> $data</span>); ++<span>$i</span>) { <span>$str</span> .= <span>$data</span>[<span>$i</span>] ^ <span>$masks</span>[<span>$i</span> % <span>4</span>]; } <span>return</span><span>$str</span>; } <span>//发送消息</span><span><span>function</span><span>sendMessage</span><span>(<span>$msg</span>, <span>$cilent</span>)</span> {</span><span>try</span>{ <span>return</span> socket_write(<span>$cilent</span>, <span>$msg</span>, strlen(<span>$msg</span>)); } <span>catch</span> (\<span>Exception</span><span>$e</span>){ <span>return</span><span>$e</span>; } } <span>//编码</span><span><span>function</span><span>code</span><span>(<span>$str</span>)</span> {</span><span>$b1</span> = <span>0x80</span> | (<span>0x1</span> & <span>0x0f</span>); <span>$length</span> = strlen(<span>$str</span>); <span>if</span> (<span>$length</span> 125</span>) <span>$header</span> = pack(<span>'CC'</span>, <span>$b1</span>, <span>$length</span>); <span>elseif</span> (<span>$length</span> ><span>125</span> && <span>$length</span> 65536) <span>$header</span> = pack(<span>'CCn'</span>, <span>$b1</span>, <span>126</span>, <span>$length</span>); <span>elseif</span> (<span>$length</span> >= <span>65536</span>) <span>$header</span> = pack(<span>'CCNN'</span>, <span>$b1</span>, <span>127</span>, <span>$length</span>); <span>else</span> { <span>return</span><span>false</span>; } <span>return</span><span>$header</span>.<span>$str</span>; } }</code>').addClass('pre-numbering' ).hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i ').text(i)); }; $numbering.fadeIn(1700); }); });
The above has introduced the WebSocket usage notes, including relevant content. I hope it will be helpful to friends who are interested in PHP tutorials.