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--;
	}
}
原文地址:https://www.cnblogs.com/wzbury/p/14016701.html