WebSocket的端点,以事件的角度看,有四个生命周期事件:css
以注解来声明这的话,能够用@OnOpen、@OnMessage、@OnError和@OnClose这四个注解。html
以一个例子来体现WebSocket的生命周期:java
点击打开链接按钮,与端点进行链接,这个时候会执行@OnOpen修饰的函数。jquery
点击发送消息,向端点发送文本框中的内容,这个时候会执行@OnMessage修饰的函数。git
点击关闭客户端链接按钮,客户端终端与端点的链接,这个时候会调用@OnClick修饰的函数。github
点击关闭服务端链接:web
端点关闭链接,关闭时大多数会产生一个异常会执行由@OnError修饰的函数,具体代码以下:数据库
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.net.bysoft</groupId> <artifactId>websocketapp</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <!-- servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- https://mvnrepository.com/artifact/javax/javaee-api --> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>7.0</version> </dependency> <!-- https://mvnrepository.com/artifact/javax.websocket/javax.websocket-api --> <dependency> <groupId>javax.websocket</groupId> <artifactId>javax.websocket-api</artifactId> <version>1.0</version> <scope>provided</scope> </dependency> </dependencies> </project>
服务端代码:apache
package cn.net.bysoft.websocketapp.lesson2; import java.io.IOException; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; @ServerEndpoint("/lifecycle") public class LifeCycle { private static String START_TIME = "Start Time"; private Session ws_session; @OnOpen public void onOpen(Session ws_session) { // 设置session,并记录创建链接时间 this.ws_session = ws_session; ws_session.getUserProperties().put(START_TIME, System.currentTimeMillis()); // 通知客户端链接成功 this.sendMessage("success:opened."); } @OnMessage public void onMessage(String message) { // 若是客户端发送过来close,则关闭链接 if ("close".equals(message)) { try { // 关闭前向客户端发送消息 this.sendMessage("danger:server closing after " + this.getConnectionSeconds() + "s."); // 关闭链接 ws_session.close(); } catch (IOException e) { System.out.println("Method: onMessage, Error closeing session " + e.getMessage()); } return; } // 若是消息不是close,则正常处理,处理完毕后通知客户端 this.sendMessage("info:processed a message."); } @OnError public void onError(Throwable t) { // 发生异常时,若是链接仍是打开状态,则通知客户端错误信息 if (ws_session.isOpen()) { this.sendMessage("warning:Error:" + t.getMessage()); } } @OnClose public void onClose() { // 关闭链接时,须要作的事情在该函数内完成,例如关闭数据库链接等 System.out.println("serivce close."); } private void sendMessage(String message) { try { // 以同步的方式向客户端发送消息 ws_session.getBasicRemote().sendText(message); } catch (IOException e) { System.out.println("Method: sendMessage, Error closeing session " + e.getMessage()); } } private int getConnectionSeconds() { long millis = System.currentTimeMillis() - ((Long) this.ws_session.getUserProperties().get(START_TIME)); return (int) millis / 1000; } }
客户端编码:bootstrap
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <!-- 新 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css"> <!-- 可选的Bootstrap主题文件(通常不用引入) --> <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap-theme.min.css"> <!-- jQuery文件。务必在bootstrap.min.js 以前引入 --> <script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script> <!-- 最新的 Bootstrap 核心 JavaScript 文件 --> <script src="http://cdn.bootcss.com/bootstrap/3.3.0/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <h1>WebSocket的生命周期</h1> <div class="row"> <div class="col-md-12"> <p> <button type="button" class="btn btn-primary" onclick="open_connection()">打开链接</button> <button type="button" class="btn btn-danger" onclick="closeServer()">关闭服务端链接</button> <button type="button" class="btn btn-danger" onclick="closeClient()">关闭客户端链接</button> </p> </div> </div> <div class="row"> <form class="form-inline" role="form"> <div class="col-md-12"> <div class="form-group"> <div class="input-group"> <div class="input-group"> <span class="input-group-addon"><span class="glyphicon glyphicon-send"></span></span> <input id="txtMessage" type="text" class="form-control" placeholder="Send Message"> </div> <button type="button" class="btn btn-info" onclick="messageClick()">发送消息</button> </div> </div> </div> </form> </div> <div class="row"> <div class="col-md-12"> <p id="output"> <br> </p> </div> </div> </div> </body> <script> var lifecycle_websocket = null; function init() { output = document.getElementById("output"); } function dispose() { lifecycle_websocket.close(); lifecycle_websocket = null; } function open_connection() { if (lifecycle_websocket == null) { lifecycle_websocket = new WebSocket( "ws://localhost:8080/websocketapp/lifecycle"); lifecycle_websocket.onmessage = function(evt) { displayMessage(evt.data); } lifecycle_websocket.onclose = function(evt) { displayMessage(evt.data); } lifecycle_websocket.onerror = function(evt) { displayMessage(evt.data); } } } function messageClick() { send_message(document.getElementById("txtMessage").value); } function closeServer() { send_message("close"); } function closeClient() { lifecycle_websocket.close(); displayMessage("danger:client closed.") } function send_message(message) { lifecycle_websocket.send(message); } function displayMessage(message) { var flag = message.substring(0, message.indexOf(':')); var data = message.substring(message.indexOf(':') + 1); var pre = document.createElement("p"); // 调用bootstrap样式 pre.className = "text-" + flag; pre.innerHTML = data; output.appendChild(pre); } window.addEventListener("load", init, false); window.addEventListener("unload", dispose, false); </script> </html>