2.WebSocket編程—生命週期

WebSocket的生命週期

    WebSocket的端點,以事件的角度看,有四個生命週期事件:css

  1. 打開事件:此事件發生在端點上創建鏈接時而且在任何其餘事件發生以前;
  2. 消息事件:此事件在接收WebSocket對話中另外一端發送的消息。它能夠發生在WebSocket端點接收了打開事件以後而且在接收關閉事件關閉以前的任什麼時候刻發生;
  3. 錯誤事件:此事件在WebSocket鏈接或端點發生錯誤時發生;
  4. 關閉事件:此事件在WebSocket鏈接或者端點發生錯誤時發生;

    以註解來聲明這的話,能夠用@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>

源碼地址:https://github.com/XuePeng87/websocketapp

相關文章
相關標籤/搜索