1. 程式人生 > 實用技巧 >websocket demo

websocket demo

websocket技術的好處:實現客戶端(瀏覽器)和伺服器的雙向通訊。

專案目錄結構:

專案

pom.xml

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>top.wz</groupId>
	<artifactId>MAVEN-WEBSOCKET-DEMO</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>



	<dependencies>
		<dependency>
			<groupId>javax</groupId>
			<artifactId>javaee-api</artifactId>
			<version>7.0</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>


	<!-- tomcat外掛控制 -->
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.tomcat.maven</groupId>
				<artifactId>tomcat7-maven-plugin</artifactId>
				<version>2.2</version>
				<configuration>
					<!--埠控制 -->
					<port>8080</port>
					<!--專案路徑控制意味著http://localhost:8080/abc -->
					<path>/</path>
					<!--編碼 -->
					<uriEncoding>UTF-8</uriEncoding>
				</configuration>
			</plugin>
			<!-- maven外掛控制 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
					<encoding>utf-8</encoding>
				</configuration>
			</plugin>
		</plugins>
	</build>

</project>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.5"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
	
	
</web-app>

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>web socket</title>
</head>
<body>
	Welcome
	<br />
	<input id="text" type="text" />
	<button onclick="send()">傳送訊息</button>
	<hr />
	<button onclick="closeWebSocket()">關閉WebSocket連線</button>
	<hr />
	<div id="message"></div>
</body>

<script type="text/javascript">
	var websocket = null;

	 //判斷當前瀏覽器是否支援WebSocket
	if ('WebSocket' in window) {
		websocket = new WebSocket("ws://localhost:8080/websocket");
	} else {
		alert("the browser not support websocket");
	}
	//連線發生錯誤的回撥方法
	websocket.onerror = function() {
		setMessageInnerHTML("WebSocket連線發生錯誤");
	}
	
	//連線成功建立的回撥方法
	websocket.onopen = function() {
		setMessageInnerHTML("WebSocket連線成功");
	}

	//接收到訊息的回撥方法
	websocket.onmessage = function() {
		setMessageInnerHTML(event.data);
	}

	//監聽視窗關閉事件,當視窗關閉時,主動去關閉websocket連線,防止連線還沒斷開就關閉視窗,server端會拋異常
	websocket.onclose = function() {
		setMessageInnerHTML("WebSocket連線關閉");
	}

	//監聽視窗關閉事件,當視窗關閉時,主動去關閉websocket連線,防止連線還沒斷開就關閉視窗,server端會拋異常。
	window.onbeforeunload = function() {
		closeWebSocket();
	}

	//將訊息顯示在網頁上
	function setMessageInnerHTML(innerHTML) {
		document.getElementById('message').innerHTML += innerHTML + '<br/>';
	}

	//關閉WebSocket連線
	function closeWebSocket() {
		websocket.close();
	}

	//傳送訊息
	function send() {
		var message = document.getElementById('text').value;
		websocket.send(message);
	}
</script>
</html>

WebSocketTest.java

package socket;

import java.util.Date;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint("/websocket")
public class WebSocketTest {
	
	/** 記錄當前客戶端的連線數 */
	private static int onlineCount = 0;
	
	//concurrent包的執行緒安全Set,用來存放每個客戶端對應的MyWebSocket物件。若要實現服務端與單一客戶端通訊的話,可以使用Map來存放,其中Key可以為使用者標識
	private static CopyOnWriteArraySet<WebSocketTest> webSocketTests = new CopyOnWriteArraySet<WebSocketTest>();
	
	//與某個客戶端的連線會話,需要通過它來給客戶端傳送資料
	private Session session;
	
	/**
	 * 連線成功時呼叫的方法
	 * @param session 可選的引數。session為與某個客戶端的連線會話,需要通過它來給客戶端傳送資料
	 */
	@OnOpen
	public void onOpen(Session session) {
		this.session = session;
		webSocketTests.add(this);
		addOnlineCount();
		System.out.println("增加一個連線,現在連線數:" + getOnlineCount());
		
		// 更新時間
		try {
			sendTime();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 連線關閉呼叫的方法
	 */
	@OnClose
	public void onClose() {
		webSocketTests.remove(this);
		subOnlineCount();
		System.out.println("減少一個連線,現在連線數:" + getOnlineCount());
	}
	
	/**
	 * 收到客戶端訊息後呼叫的方法
	 * @param message 客戶端傳送過來的訊息
	 * @param session 可選引數
	 */
	@OnMessage
	public void onMessage(String message, Session session) {
		System.out.println("來自客戶端的訊息:"+message);
		// 群發訊息
		for (WebSocketTest item : webSocketTests) {
			try {
				item.sendMessage(message);
			} catch (Exception e) {
				e.printStackTrace();
				continue;
			}
		}
	}
	
	/**
	 * 傳送資訊
	 * @param message 訊息
	 * @throws Exception
	 */
	public void sendMessage(String message) throws Exception {
//		this.session.getAsyncRemote().sendText(message);
		this.session.getBasicRemote().sendText(message);
		System.out.println(this.session.getBasicRemote());
	}
	
	// 迴圈更新時間併發送
	public void sendTime() throws Exception {
		while (true) {
			Thread.sleep(1000);
			Date date = new Date();
			this.session.getBasicRemote().sendText(date.toString());
		}
	}
	
	
	
	public static synchronized void addOnlineCount() {
		WebSocketTest.onlineCount++;
	}
	
	public static synchronized int getOnlineCount() {
		return WebSocketTest.onlineCount;
	}
	
	public static synchronized void subOnlineCount() {
		WebSocketTest.onlineCount--;
	}
}