大佬教程收集整理的这篇文章主要介绍了HTML5下的WebSocket学习笔记,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
1.WebSocket API --- 基于JavaScript,包括 WebSocket原始对象,事件,方法和属性,通过WebSocket API可以连接到本地货远程的Server服务器,发送和接收消息,关闭连接 2.使用WebSocket的典型流程: 1.检查浏览器是否支持WebSocket --- Check for WebSocket browser support 2.创建WebSocket的js对象 --- Create an instance of the WebSocket JS Object 3.连接WebSocket服务器 --- Connect to the WebSocket Server 4.注册WebSocket事件 --- Register for the WebSocket events 5.根据用户交互进行数据传输 --- Perform the proper data transmission according to users' actions 6.关闭连接 --- Close the connection 1.Browser Support --- 检测浏览器是否支持WebSocket if(window.WebSocket){ console.log("WebSocket supported"); //通过WebSocket进行操作 }else{ //不支持WebSocket,给出相应的提示和处理策略 alert("Consider updating your browser for a richer experience"); } 2.The WebSocket Object --- WebSocket的JavaScript对象 new WebSocket(url) --- url:表示WebSocket要连接的服务器 var socket = new WebSocket("ws://echo.websocket.org"); 说明: 当创建一个WebSocket的JS对象后,它会立即连接到指定的服务器 3.WebSocket 事件 --- WebSocket Events WebSocket的四个主要事件: 事件 对应方法 Open onopen Message onmessage Close onclose Error onerror 事件处理的两种方式 1.通过事件的对应方法 --- 推荐:简单结构清晰 2.addEventListener方法去实现事件处理 说明:当不同的事件发生时,会触发相应的方法,执行逻辑代码 4.WebSocket的事件处理 onopen -- 事件在连接成功时触发,达成第一个握手,准备传输数据 eg: socket.onopen = function(event){ console.log("Connection established"); //在这类可以初始化资源,并展示一些用户友好提示信息 var label = document.getElementById("status-label"); label.innerHTML="Connection established"; } onmessage -- 数据传输事件,客户端随时监听Server,当服务器端发送给客户端数据时触发 --- 数据包括:文本、图片、二进制数据等 eg: socket.onmessage = function(event){ console.log("Data received"); if(typeof event.data == "string"){ var label = document.getElementById("status-label"); label.innerHTML = event.data; } } onclose -- 关闭客户端与服务器的连接,不能在进行数据的传输。 关闭连接的原因有多种:服务器关闭,客户端调用close()方法关闭,或者TCP错误 --- 可通过 code,reason,wasClean参数检测连接关闭的原因 code --- 用一个唯一的数字,表示连接中断的原因 reason --- 连接中断的原因 wasClean --- 用于判断连接关闭,是因为服务器的原因,还是未知的网络错误 eg: socket.onclose = function(event){ console.log("Connections closed"); var code = event.code; var reason = event.reason; var wasClean = event.wasClean; var label = document.getElementById("status-label"); if(wasClean){ label.innerHTML = "Connection closed normally"; }else{ label.innerHTML ="Connection closed with message "+reason+"(Code: "+code+")"; } } onerror -- 出错时触发的事件,该事件出发后,会接着触发close事件,终止连接 --- 注意出错时给出提示,并尝试重新建立连接 eg: socket.onerror = function(event){ console.log("Error occurred"); //出错提示 var label = document.getElementById("status-label"); label.innerHTML = "Error: "+event; } 5.WebSocket的操作处理Actions 即:处理方法 两种 send()和close() 1.send() --- 当连接成功后,客户端可与服务端进行数据传输,send()方法用于传输数据到服务器 eg: var textView = document.getElementById("text-view"); var buttonSend = document.getElementById("send-button"); buttonSend.onClick = function(){ //发送数据 if(socket.readyState == WebSocket.OPEN){ socket.send(textView.value); } } 特别注意: 只有在连接成功时才能发送数据,因此,要么把send()方法放在onopen事件中处理,要么在发送数据是进行判断:当前连接是否成功 2.close() --- 中断连接 eg: 通过点击按钮事件来中断当前连接 var textView = document.getElementById("text-view"); var buttonStop = document.getElementById("stop-button"); buttonSend.onClick = function(){ if(socket.readyState == WebSocket.OPEN){ socket.close(); //也可之前提到的传递code和reason参数 //socket.close(1000,"Deliberate disconnection"); } } 6.WebSocket的属性 Properties url --- 返回WebSocket的URL protocol --- 返回Server服务器使用的协议 readyState --- 连接状态 WebSocket.OPEN --- 已连接 WebSocket.CLOSED --- 已关闭 WebSocket.CONNECTING --- 正在连接 WebSocket.CLOSING --- 正在关闭 bufferedAmount --- 返回send()方法被调用时,已进入队列但尚未发送到服务器的总字节数 binaryType --- 返回接收到的二进制数据 -- (onmessage事件被触发时) 7.WebSocket的Server 1.流程 Server Client Create a server on localhost:8080 Start running initial handshake: establish connection <------------ Request connection Handle the incoming message <------------ Send message 2.Server处理 1.初始化WebSocket的地址 2.处理客户端的各类事件 OnOpen,OnClose,OnMessage,以及向客户端发送数据 3.使用Java实现的WebSocket服务器 --- 需要JDK1.7+ --- 需要Tomcat7+下的lib中Tomcat-websocket.jar和websocket-api.jar 完整的例子 WebSocketTest1.java package com.jay.websocket; import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import java.io.IOException; /** * Java 实现的WebSocket服务器,* 实现客户端的onopen,onmessage,onclose事件的处理方法 * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端。注解的值将被用于监听用户连接的终端访问URL地址。 onOpen 和 onClose 方法分别被@OnOpen和@OnClose 所注解。这两个注解的作用不言自明:他们定义了当一个新用户连接和断开的时候所调用的方法。 onMessage 方法被@OnMessage所注解。这个注解定义了当服务器接收到客户端发送的消息时所调用的方法。注意:这个方法可能包含一个javax.websocket.Session可选参数(在我们的例子里就是session参数)。如果有这个参数,容器将会把当前发送消息客户端的连接Session注入进去。 本例中我们仅仅是将客户端消息内容打印出来,然后首先我们将发送一条开始消息,之后间隔5秒向客户端发送1条测试消息,共发送3次,最后向客户端发送最后一条结束消息。 * Created by Jay He on 2015/9/19. */ @ServerEndpoint("/websocket") public class WebSocketTest1 { /** * 这里用于接收客户端的数据和发送给客户端数据 * @param message * @param session * @throws IOException * @throws InterruptedException */ @OnMessage public void onMessage(String message,Session session) throws IOException,InterruptedException { // Print the client message for testing purposes System.out.println("Received: " + message); // Send the first message to the client session.getBasicRemote().sendText("This is the first server message"); // Send 3 messages to the client every 5 seconds int sentMessages = 0; while(sentMessages < 3){ Thread.sleep(5000); session.getBasicRemote(). sendText("This is an intermediate server message. Count: " + sentMessages); sentMessages++; } // Send a final message to the client session.getBasicRemote().sendText("This is the last server message"); } //客户端连接 @OnOpen public void onopen() { System.out.println("Client connected"); } //断开连接 @OnClose public void onClose() { System.out.println("Connection closed"); } } 页面显示:websocket.html <!DOCTYPE html> <html> <head lang="en"> <Meta charset="UTF-8"> <title>Testing WebSocket</title> </head> <body> <div> <input type="submit" value="点击请求WebSocket服务器" onclick="start()" /> </div> <div id="messages"></div> <script type="text/javascript"> var webSocket = new WebSocket('ws://localhost:8080/JayEEDemo1/websocket'); webSocket.onerror = function(event) { onError(event) }; webSocket.onopen = function(event) { onOpen(event) }; webSocket.onmessage = function(event) { onMessage(event) }; function onMessage(event) { document.getElementById('messages').innerHTML += '<br />' + event.data; } function onOpen(event) { document.getElementById('messages').innerHTML = 'Connection established'; } function onError(event) { alert(event.data); } function start() { webSocket.send('hello'); return false; } </script> </body> </html> 8.使用WebSocket传输不同类型的数据 文本文件(String)和二进制文件(ArrayBuffer或Blob) 特别注意:WebSocket传输二进制文件时,只能选择ArrayBuffer或Blob中的一种,不能混用 eg: ArrayBuffer方式: socket.binaryType="arraybuffer"; Blob方式: socket.binaryType="blob"; 1.文本文件传输 --- 根据typeof event.data判断类型 1.String socket.onmessage=function(event){ if(typeof event.data=="string"){ console.log("Received string data"); } } 2.JSON if(typeof event.data=="string"){ //创建JSON对象 var jsonObject = JSON.parse(event.data); //根据key获取JSON值 var username=jsonObject.name; var userMessage = jsonObject.message; } 2.二进制文件传输 1.ArrayBuffer --- 用于传输小型二进制文件,图片等 1.发送二进制文件 通过拖拽事件,处理图片,每次拖进一条图片,通过js的FileReader来读取文件生成一个ArrayBuffer, 当reader处理完file后,在onload事件中,使用WebSocket将数据发送给服务器 1.通过ArrayBuffer方式发送图片给服务器 document.ondrop = function(event){ var file = event.dataTransfer.files[0]; var reader = new FileReader(); reader.readAsArrayBuffer(file); reader.onload = function(){ socket.send(reader.result); } return false; } 2.通过Blob方式发送图片给服务器 document.ondrop = function(event){ var file = event.dataTransfer.files[0]; //直接发送以blob方式 socket.send(file); return false; } 特别说明: 使用浏览器的拖拽事件时,要自定义方法,覆盖浏览器默认的事件处理,防止浏览器默认事件处理影响自己写的处理方法 eg: //覆写拖动对象事件 document.ondragover = function(event){ event.preventDefault(); } 说明: dragStart --- 拖动开始 dragOver --- 停放位置 drop --- 拖动结束 2.接收二进制文件 js接收二进制文件时,通过instanceof判断是否是ArrayBuffer socket.onmessage = function(event){ if(event.data instanceof ArrayBuffer){ var buffer = event.data; } } 2.Blobs --- 用于传输大的二进制文件,视频和其他二进制大文件等 需要在展示时判断Server传递过来的是否是Blob eg:通过blob形式接收Server传递的图片 socket.message=function(event){ if(event.data instanceof blob){ //1.获取二进制文件 var blob = event.data; //2.为Blob对象创建新的URL window.URL = window.URL || window.webkitURL; var source = window.URL.createObjectURL(blob); //3.创建image标签 var image = document.createElement("img"); image.src = source; image.alt = "Image generated from blob"; //4.将创建的标签插入到document尾部 document.body.appendChild(image); } } eg:通过blob接收视频流 -- Video的本质是连续的图片,又帧组成后形成了视频 <img id="video" src="" alt="Video streaming"/> var video = document.getElementById("video"); socket.onmessage = function(event){ if(event.data instanceof Blob){ //1.获取二进制数据 var blob = event.blob; //2.为blog对象创建新的的URL window.URL = window.URL || window.webkitURL; var source = window.URL.createObjectURL(blob); //3.更新资源 video.src = source; //4.释放申请的内存 window.URL.revokeObjectURL(source); } } 代码说明: 1.类似上一个图片传输,但这里预先在html中引用了一个<img>标签,在通讯时,不停的改变其src属性 2.每次设置src后,通过revokeObject方法释放URL所在内存 3.通过JSON传递数据 eg: <label id="status-label">Status...</label> <input type="text" id="name-view" placeholder="Your name" /> <input type="text" id="text-view" placeholder="Type your message..." /> js: 发送JSON数据 var nameView = document.getElementById("name-view"); buttonSend.onclick = function(event){ if(socket.readyState == WebSocket.OPEN){ //构造json,并发送 var json = "{'name':'"+nameView.value+"','message':'"+textView.value+"'}"; socket.send(json); textView.value=""; } } 接收服务端的JSON数据 socket.onmessage = function(event){ if(typeof event.data == "String"){ //显示信息 var jsonObject = eval('('+event.data+')'); var userName = jsonObject.name; var userMessage = jsonObject.message; chatArea.innerHTML = charArea.innerHTML+"<p><strong>"+userName+"</strong>:"+userMessage+"</p>" } } 9.WebSocket的安全问题: 客户端发送的Header The following is an example of WebSocket header sent from a client: GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Origin: http://example.com Pragma: no-cache Cache-Control: no-cache Sec-WebSocket-Key: AAf/gvkPw6szicrMH3Rwbg== Sec-WebSocket-Version: 13 Sec-WebSocket-Extensions: x-webkit-deflate-frame 服务器端返回的Header HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= 常见的攻击类型: DoS攻击(Denial of Service) 拒绝服务攻击,通过一定的手段使得请求资源对用户不可用 eg:循环攻击,导致服务器繁忙或无法响应 中间人攻击(Man-in-the-middle),通常是信息未加密导致 XSS跨站脚本攻击 ,通过植入脚本实现攻击,让脚本在客户端机器上执行 --- 通过传输数据的转码可以避免这类攻击 WebSocket协议自带的 wss 可保证安全的传输,防止入侵 10.异常的处理与反馈 1.浏览器的支持问题 2.不支持的浏览器,通过一定技术手段去完成WebSocket的处理 eg:socketio.js 常见的错误处理: 1.内部异常 能够控制的代码或逻辑异常 2.外部异常 网络连接问题 --- 检查网络可用性 通过HTML5的navigator对象,判断网络是否可用 eg:1.检查网络可用性 if(navigator.onLine){ alert("You are OnLine"); }else{ alert("You are OffLine"); } eg:2.通知用户网络不可用,并尝试重新连接 socket.onclose = function(event){ //先检测原因,再重新连接 if(event.code!=1000){ //event.code==1000表示是连接正常关闭 if(!navigator.onLine){ alert("You are offline. Please connect to the Internet and try again"); } } } 处理浏览器HTML5不支持的问题 使用polyfills方案的插件库,来解决老版本浏览器不支持HTML5的问题 常用的js库: sockJS,socket.io和jQuery的插件库 Graceful WebSocket --- https://github.com/ffdead/jquery-graceful-websocket eg: 使用Graceful WebSocket库,来实现HTML5的功能 1.引入两个库 <script src=" jquery-1.9.1.min.js"></script> <script src="jquery.gracefulWebSocket.js"></script> 2.使用 $.gracefulWebSocket(address) 代替 new WebSocket(address) 创建WebSocket对象 var socket = $.gracefulWebSocket("ws://localhost:8181") 3.实现4个常用事件函数 socket.onopen = function(event){ //处理连接事件 } socket.onclose = function(event){ //处理连接关闭事件 } socket.onmessage = function(event){ //处理消息接收事件 } socket.onerror = function(event){ //处理异常事件 } 发送消息: socket.send("Hello server! I'm a WebSocket polyfill."); 一个WebSocket的实践: HTML5 WebSocket实现实时视频文字传输 客户端 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <script type="text/javascript"> //1.初始化WebSocket对象 var webSocket = new WebSocket("ws://localhost:8080/webSocket"); //向服务器发送消息 //webSocket.send("hell0"); //查看WebSocket当前状态 //alert(webSocket.readyState); //2.定义WebSocket的事件方法 webSocket.onopen = function(event){ alert("已经建立连接"); } webSocket.onmessage = function(event){ //收到服务器消息,使用event.data提取消息内容 -- 可以是文本,也可能是二进制文件 writeToScreen(event.data); } webSocket.onclose = function(event){ alert("已经关闭连接"); } webSocket.onerror = function(event){ alert("产生异常"); //将异常信息打印在屏幕上 writeToScreen(event.message); } //发送消息给服务器 function sendMsg(){ if(webSocket.readyState == WebSocket.OPEN){ msg = document.getElementById("msg").value; webSocket.send(msg); writeToScreen("发送成功!"); }else{ writeToScreen("发送失败!"); } } //将信息写到屏幕 function writeToScreen(message){ var pre = document.createElement("p"); pre.style.wordWrap="break-word"; pre.innerHTML+=message; output.appendChild(pre); } </script> </head> <body> <div> <input type="text" id="msg" value="beyond is number one!" /> <button onclick="sendMsg()">send</button> </div> <div id="output"></div> </body> </html> 代码说明: 1.readyState表示的四种状态: CONNECTING(0) --- 还未建立连接 OPEN(1) --- 已建立连接,可进行通讯 CLOSING(3) --- 正在关闭连接 CLOSED(4) --- 连接已经关闭或无法打开 2.WebSocket的协议,通常是 ws 或 wss(加密通信) 3.send()方法将数据发送到服务器端 4.close()方法关闭连接 5.几个触发事件: onopen --- 连接建立,即:握手成功触发的事件 onmessage --- 收到服务器消息时触发的事件 onerror --- 异常触发的事件 onclose --- 关闭连接触发的事件 服务器端
Server端
<pre>import java.io.IOException; import java.util.Hashtable; import java.util.Map; import java.util.Set; import java.util.logging.Logger; import javax.websocket.CloseReason; import javax.websocket.CloseReason.CloseCodes; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.RemoteEndpoint; import javax.websocket.Session; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; //注意此访问地址格式如:"ws://"+ window.location.host+"/${pageContext.request.contextPath}/game"是ws开头的,而不是以http:开头的. @ServerEndpoint(value = "/game") public class Scoket { private Logger logger = Logger.getLogger(this.getClass().getName()); static Map<String,Session> sessionMap = new Hashtable<String,Session>(); @OnOpen public void onOpen(Session session) { sessionMap.put(session.getId(), session); } @OnMessage public void onMessage(String unscrambledWord, Session session) { broadcastAll("message",unscrambledWord); } /** * 广播给所有人 * @param message */ public static void broadcastAll(String type,String message){ Set<Map.Entry<String,Session>> set = sessionMap.entrySet(); for(Map.Entry<String,Session> i: set){ try { i.getValue().getBasicRemote().sendText("{type:'"+type+"',text:'"+message+"'}"); } catch (Exception e) { e.printStackTrace(); } } } @OnClose public void onClose(Session session, CloseReason closeReason) { sessionMap.remove(session.getId()); logger.info(String.format("Session %s closed because of %s", session.getId(), closeReason)); } @OnError public void error(Session session, java.lang.Throwable throwable){ sessionMap.remove(session.getId()); System.err.println("session "+session.getId()+" error:"+throwable); } }
注解说明:
@ServerEndpoint 将POJO转换为服务器端点
@ClientEndpoint 将Pojo转换为客户端端点
@OnMessage 处理WebSocket的onMessage事件
@OnOpen 处理WebSocket的open事件
@OnClose 处理WebSocket的close事件
@OnError 处理WebSocket的error事件
Client端
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <Meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script src="http://lib.sinaapp.com/js/jquery/1.7.2/jquery.min.js" type="text/javascript"></script> <script type="text/javascript"> var socket =null; $(function(){ function parSEObj(strData){//转换对象 return (new Function( "return " + strData ))(); }; //创建socket对象 socket = new WebSocket("ws://"+ window.location.host+"/${pageContext.request.contextPath}/game"); //连接创建后调用 socket.onopen = function() { $("#showMsg").append("连接成功...<br/>"); }; //接收到服务器消息后调用 socket.onmessage = function(message) { var data=parSEObj(message.data); if(data.type=="message"){ $("#showMsg").append("<span style='display:block'>"+data.text+"</span>"); }else if(data.type=="background"){ $("#showMsg").append("<span style='display:block'>系统改变背景地址,背景地址是:"+data.text+"</span>"); $("body").css("background","url("+data.text+")"); } }; //关闭连接的时候调用 socket.onclose = function(){ alert("close"); }; //出错时调用 socket.onerror = function() { alert("error"); }; $("#sendButton").click(function() { socket.send($("#msg").val()); }); $("#abcde").click(function(){ $.post("${pageContext.request.contextPath}/backgroundimg"); }); }); </script> </head> <body> <div id="showMsg" style="border: 1px solid; width: 500px; height: 400px; overflow: auto;"></div> <div> <input type="text" id="msg" /> <input type="button" id="sendButton" value="发送" /> <input type="button" value="改变背景" id="abcde" /> </div> </body> </html>
以上是大佬教程为你收集整理的HTML5下的WebSocket学习笔记全部内容,希望文章能够帮你解决HTML5下的WebSocket学习笔记所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。