WebSocket使用笔记
一、简介
对于网页中快速的发送接收多条消息,WebSocket非常适合来解决这种需求。此次使用WebSocket来搭建一个聊天网页应用。主要涉及的客户端的实现,服务端使用是一个php来实现的WebSocket服务端,在本篇中暂不做详细介绍。
主要的JavaScript代码有这些
- new WebSocket 创建一个websocket对象
- socket.onopen 建立连接后触发
- socket.onerror 错误时触发
- socket.onmessage 接受到数据时触发
- socket.onclose 连接关闭时触发
- socket.send() 发送数据
二、成果
最终实现的是向服务器发消息,服务器返回相同消息,效果如下图所示。在线展示版点击图片下发链接
在线版本在这里
三、代码
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服务端代码,已封装成类
<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>
以上就介绍了WebSocket使用笔记,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

如何使用WebSocket和JavaScript实现在线语音识别系统引言:随着科技的不断发展,语音识别技术已经成为了人工智能领域的重要组成部分。而基于WebSocket和JavaScript实现的在线语音识别系统,具备了低延迟、实时性和跨平台的特点,成为了一种被广泛应用的解决方案。本文将介绍如何使用WebSocket和JavaScript来实现在线语音识别系

随着互联网技术的不断发展,实时视频流已经成为了互联网领域的一个重要应用。要实现实时视频流播放,其中的关键技术包括WebSocket和Java。本文将介绍如何结合使用WebSocket和Java实现实时视频流播放,并提供相关的代码示例。一、什么是WebSocketWebSocket是一种在单个TCP连接上进行全双工通信的协议,它在Web

随着互联网技术的不断发展,实时通信已经成为了日常生活中不可缺少的一部分。利用WebSockets技术可以实现高效、低延迟的实时通信,而PHP作为互联网领域使用最广泛的开发语言之一,也提供了相应的WebSocket支持。本文将为大家介绍如何使用PHP和WebSocket实现实时通信,并提供具体的代码示例。一、什么是WebSocketWebSocket是一种在单

golangWebSocket与JSON的结合:实现数据传输和解析在现代的Web开发中,实时数据传输变得越来越重要。WebSocket是一种用于实现双向通信的协议,与传统的HTTP请求-响应模型不同,WebSocket允许服务器向客户端主动推送数据。而JSON(JavaScriptObjectNotation)是一种用于数据交换的轻量级格式,它简洁易读

WebSocket与JavaScript:实现实时监控系统的关键技术引言:随着互联网技术的快速发展,实时监控系统在各个领域中得到了广泛的应用。而实现实时监控的关键技术之一就是WebSocket与JavaScript的结合使用。本文将介绍WebSocket与JavaScript在实时监控系统中的应用,并给出代码示例,详细解释其实现原理。一、WebSocket技

PHP和WebSocket:实现实时数据传输的最佳实践方法引言:在Web应用程序开发中,实时数据传输是一项非常重要的技术需求。传统的HTTP协议是一种请求-响应模式的协议,不能有效地实现实时数据传输。为了满足实时数据传输的需求,WebSocket协议应运而生。WebSocket是一种全双工通信协议,它提供了一种在单个TCP连接上进行全双工通信的方式。相比于H

JavaWebsocket如何实现在线白板功能?在现代互联网时代,人们越来越注重实时协作和互动的体验。在线白板就是一种基于Websocket实现的功能,它能够使多个用户实时协作编辑同一个画板,完成绘图和标注等操作,为在线教育、远程会议、团队协作等场景提供了便捷的解决方案。一、技术背景WebSocket是HTML5提供的一种新的协议,它在同一条TCP连接上实

在本文中,我们将比较服务器发送事件(SSE)和 WebSocket,两者都是用于传递数据的可靠方法。我们将在八个方面对它们进行分析,包括通信方向、底层协议、安全、易用性、性能、消息结构、易用性和测试工具。这些方面的比较总结如下:类别服务器发送事件 (SSE)WebSocket通信方向单向双向底层协议HTTPWebSocket 协议安全与 HTTP 相同存在安全漏洞易用性设置简单设置复杂性能消息发送速度快受消息处理和连接管理影响消息结构纯文本文本或二进制易用性广泛可用对 WebSocket 集成有
