用註解@ServerEndpoint(“/websocket”)
- 兩種方法實現代碼地址(包含相關jar包) :http://pan.baidu.com/s/1dF2ElVV 密碼:8x6x
方法1:用註解@ServerEndpoint(“/websocket”)
方法2:spring-websocket-4.3.6.RELEASE.jar實現 - 註解@ServerEndpoint(“/websocket”)實現websoket(實現定時向瀏覽器發送定時任務)
配置文件applicationContext-java.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<bean name="monitor" class="com.spring.java.websocket.Monitor" lazy-init="false" init-method="sendMsg"></bean>
</beans>
Monitor類
package com.spring.java.websocket;
import com.spring.java.websocket.WebSocketTest;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Monitor implements Runnable {
@Override
public void run() {
WebSocketTest webSocketTest = new WebSocketTest();
webSocketTest.sendMsg("當前時間:" + new Date());
}
public void sendMsg() {
ScheduledExecutorService newScheduledThreadPool = Executors.newSingleThreadScheduledExecutor();
newScheduledThreadPool.scheduleWithFixedDelay(new Monitor(), 20, 5, TimeUnit.SECONDS);
}
}
測試類WebSocketTest
package com.spring.java.websocket;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* @ServerEndpoint 註解是一個類層次的註解,它的功能主要是將目前的類定義成一個websocket服務器端,
* 註解的值將被用於監聽用戶連接的終端訪問URL地址,客戶端可以通過這個URL來連接到WebSocket服務器端
* @author uptop
*/
@ServerEndpoint("/websocket")
public class WebSocketTest {
//靜態變量,用來記錄當前在線連接數。應該把它設計成線程安全的。
private static int onlineCount = 0;
//concurrent包的線程安全Set,用來存放每個客戶端對應的MyWebSocket對象。若要實現服務端與單一客戶端通信的話,可以使用Map來存放,其中Key可以爲用戶標識
public static CopyOnWriteArraySet<WebSocketTest> webSocketSet = new CopyOnWriteArraySet<WebSocketTest>();
//與某個客戶端的連接會話,需要通過它來給客戶端發送數據
private Session session;
/**
* 連接建立成功調用的方法
*
* @param session 可選的參數。session爲與某個客戶端的連接會話,需要通過它來給客戶端發送數據
*/
@OnOpen
public void onOpen(Session session) {
this.session = session;
webSocketSet.add(this); //加入set中
addOnlineCount(); //在線數加1
System.out.println("有新連接加入!當前在線人數爲" + getOnlineCount());
}
/**
* 連接關閉調用的方法
*/
@OnClose
public void onClose() {
webSocketSet.remove(this); //從set中刪除
subOnlineCount(); //在線數減1
System.out.println("有一連接關閉!當前在線人數爲" + getOnlineCount());
}
/**
* 收到客戶端消息後調用的方法
*
* @param message 客戶端發送過來的消息
* @param session 可選的參數
*/
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("來自客戶端的消息:" + message);
//羣發消息
for (WebSocketTest item : webSocketSet) {
try {
item.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
continue;
}
}
}
/**
* 發生錯誤時調用
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
System.out.println("發生錯誤");
error.printStackTrace();
}
/**
* 這個方法與上面幾個方法不一樣。沒有用註解,是根據自己需要添加的方法。
*
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
WebSocketTest.onlineCount++;
}
public static synchronized void subOnlineCount() {
WebSocketTest.onlineCount--;
}
public void sendMsg(String msg) {
for (WebSocketTest item : webSocketSet) {
try {
item.sendMessage(msg);
} catch (IOException e) {
e.printStackTrace();
continue;
}
}
}
}
index.jsp文件
<%@ page language="java" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>spring-javawebsoket</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>
<table id="tb" class="altrowstable">
<th align="center" colspan="9">實時信息監控</th>
</table>
</body>
<script type="text/javascript" src="js/jqueryV2.2.3.min.js"></script>
<script type="text/javascript">
var websocket = null;
//判斷當前瀏覽器是否支持WebSocket
if ('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8082/websoket_test/websocket");
}
else {
alert('當前瀏覽器 Not support websocket')
}
//連接發生錯誤的回調方法
websocket.onerror = function () {
setMessageInnerHTML("WebSocket連接發生錯誤");
};
//連接成功建立的回調方法
websocket.onopen = function () {
setMessageInnerHTML("WebSocket連接成功");
}
//接收到消息的回調方法
websocket.onmessage = function (event) {
setMessageInnerHTML(event.data);
}
//連接關閉的回調方法
websocket.onclose = function () {
setMessageInnerHTML("WebSocket連接關閉");
}
//監聽窗口關閉事件,當窗口關閉時,主動去關閉websocket連接,防止連接還沒斷開就關閉窗口,server端會拋異常。
window.onbeforeunload = function () {
closeWebSocket();
}
//將消息顯示在網頁上
function setMessageInnerHTML(innerHTML) {
var msg=innerHTML.split(" - ")
var table=document.getElementById("tb");
var row;
row=table.insertRow(1);
for(var i=0;i<msg.length;i++){
var cell = row.insertCell(i);
cell.appendChild(document.createTextNode(msg[i]));
}
if(table.rows.length>50){
table.deleteRow(table.rows.length-1);
}
// document.getElementById('message').innerHTML += innerHTML + '<br/>';
}
//關閉WebSocket連接
function closeWebSocket() {
websocket.close();
}
//發送消息
function send() {
var message = document.getElementById('text').value;
websocket.send(message);
}
</script>
</html>
web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<context-param>
<param-name>contextConfigLocation</param-name>
<!-- jave websoket -->
<!--
測試地址:http://localhost:8082/websoket_test/index.jsp
<param-value>classpath:applicationContext-java.xml</param-value>
-->
<!-- 測試地址:http://localhost:8082/websoket_test/websocket/login.action?username=ddd -->
<param-value>classpath:applicationContext-java.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
</web-app>