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--;
}
}