websocket,实际用于客户端与服务器端的全双工通信,说白话,就是一个客户端(浏览器地址栏指定的跳转页面)连接服务器端(java类,注解成一个websocket服务器端),通过服务器端的程序控制可以允许多个客户端同时连接服务器端,下面进行详解。
关键点1: new WebSocket() 时,其中的URL路径非常重要,错误的话,会连接失败
关键点2:服务器端类中的注解类字符,例如@OnOpen @OnClose,其中的大小写敏感,不过这里容易排查,因为编译时,IDEA会有错误提示
构建一个websocket服务器端,从IDEA->项目的src->右键->新建->Java Class,具体代码如下
WebSocketBroadcast.java
import org.jetbrains.annotations.Contract; import java.io.IOException; import java.util.concurrent.CopyOnWriteArraySet; import javax.websocket.*; import javax.websocket.server.ServerEndpoint; //该注解是一个类层次的注解,功能是将目前的类定义成一个websocket服务器端,注解的值将 //被用于监听用户连接的终端访问URL地址。 @ServerEndpoint("/WebSocketBroadcast") public class WebSocketBroadcast { //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。 private static int onlineCount = 0; //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识 private static CopyOnWriteArraySet<WebSocketBroadcast> websocketset = new CopyOnWriteArraySet<WebSocketBroadcast>(); //与某个客户端的连接会话,需要通过它来给客户端发送数据 private Session session; @OnOpen public void onOpen(Session session) { this.session = session; websocketset.add(this); addOnlineCount(); System.out.println("有新连接加入!当前在线人数为 " + getOnlineCount()); } @OnClose public void onClose() { websocketset.remove(this); subOnlineCount(); System.out.println("有一个连接关闭!当前在线人数为 " + getOnlineCount()); } //收到客户端发来的消息 @OnMessage public void onMessage(String message, Session session) throws IOException, InterruptedException { System.out.println("收到来自客户端的消息: " + message); } public void sendMessage(String message) throws IOException { this.session.getBasicRemote().sendText(message); } @Contract(pure = true) public static synchronized int getOnlineCount() { return onlineCount; } public static synchronized void addOnlineCount() { WebSocketBroadcast.onlineCount++; } public static synchronized void subOnlineCount() { WebSocketBroadcast.onlineCount--; } }
客户端,就是一个jsp,具体代码如下
main.jsp
<%-- Created by IntelliJ IDEA. User: svebrs Date: 2018/12/12 Time: 13:55 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <script type="text/javascript" src="${pageContext.request.contextPath}/jquery/jquery-1.11.2.min.js"></script> <title>main interface</title> </head> <body> <h2> test web app </h2> <label>dst ip:x.x.x.x, dst port:xxxxx</label> <input type="text"> <input type="button" value="send" width="200" onclick="send()"> <input type="button" value="close websocket" width="200" onclick="close_websocket()"> <input type="button" value="clear setInterval" width="200" onclick="clear_setinterval()"> <label id="message"></label> <!-- <input type="button" value="set interval" width="800"> <input type="button" value="clear interval" width="800"> --> <!-- <script type="text/javascript"> //$(document).ready(function(e) { alert('main.jsp test jquery !'); }); </script> --> <script type="text/javascript"> var websocket = null; if('WebSocket' in window) { //注意这里的地址必须为ws://localhost:8080/the_first_jsp_war_exploded/ + websocket服务器端的名字 //见 @ServerEndpoint("/WebSocketBroadcast") in WebSocketBroadcast.java websocket = new WebSocket("ws://localhost:8080/the_first_jsp_war_exploded/WebSocketBroadcast"); } else { alert("当前浏览器不支持web socket !!!"); } //websocket的四个事件, onerror, onpen, onclose, onmessage websocket.onerror = function () { set_message_in_html("websocket connect error !!"); } //一旦服务器响应了websocket连接请求,open事件触发并建立了一个连接,该事件对应的回调函数 //到open事件触发时,协议握手已经完成,websocket已经准备好发送和接收数据,说明服务器已经 //成功地处理了连接请求。 websocket.onopen = function () { set_message_in_html("websocket connect ok !!"); } websocket.onclose = function () { set_message_in_html("websocket connect close !!"); } websocket.onmessage = function () { set_message_in_html("websocket connect error !!"); } window.onbeforeunload = function () { } function set_message_in_html(innerHTML) { document.getElementById("message").innerHTML += "<br/>" + innerHTML + "<br/>"; } </script> <!--测试websocket时,下面的ajax是没有用到的 --> <script type="text/javascript"> var inter; function mvb_process() { //alert("test interval , 2000ms !!"); $.ajax({ url: 'ServletMVBProcess', data: { }, type:'post', datatype: 'json', beforeSend: function() { }, success: function(result) { }, error: function () { } }); } $(function() { //inter = setInterval(mvb_process, 2000); }); function send() { } function close_websocket() { } function clear_setinterval() { clearInterval(inter); } </script> </body> </html>