最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring和Websocket相結(jié)合實現(xiàn)消息的推送

 更新時間:2016年02月01日 10:19:47   投稿:mrr  
這篇文章主要介紹了Spring和Websocket相結(jié)合實現(xiàn)消息的推送的相關(guān)資料,本文介紹的非常詳細(xì)具有參考借鑒價值,感興趣的朋友一起學(xué)習(xí)吧

本文主要有三個步驟

1、用戶登錄后建立websocket連接,默認(rèn)選擇websocket連接,如果瀏覽器不支持,則使用sockjs進行模擬連接
2、建立連接后,服務(wù)端返回該用戶的未讀消息
3、服務(wù)端進行相關(guān)操作后,推送給某一個用戶或者所有用戶新消息 相關(guān)環(huán)境 Spring4.0.6(要選擇4.0+),tomcat7.0.55

Websocet服務(wù)端實現(xiàn)

WebSocketConfig.java

@Configuration
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(systemWebSocketHandler(),"/webSocketServer").addInterceptors(new WebSocketHandshakeInterceptor());
registry.addHandler(systemWebSocketHandler(), "/sockjs/webSocketServer").addInterceptors(new WebSocketHandshakeInterceptor())
.withSockJS();
}
@Bean
public WebSocketHandler systemWebSocketHandler(){
return new SystemWebSocketHandler();
}
}

不要忘記在springmvc的配置文件中配置對此類的自動掃描

<context:component-scan base-package="com.ldl.origami.websocket" />

@Configuration
@EnableWebMvc
@EnableWebSocket

這三個大致意思是使這個類支持以@Bean的方式加載bean,并且支持springmvc和websocket,不是很準(zhǔn)確大致這樣,試了一下@EnableWebMvc不加也沒什么影響,@Configuration本來就支持springmvc的自動掃描

registry.addHandler(systemWebSocketHandler(),"/webSocketServer").addInterceptors(new WebSocketHandshakeInterceptor())

用來注冊websocket server實現(xiàn)類,第二個參數(shù)是訪問websocket的地址

registry.addHandler(systemWebSocketHandler(), "/sockjs/webSocketServer").addInterceptors(new WebSocketHandshakeInterceptor())
.withSockJS();
}

這個是使用Sockjs的注冊方法

首先SystemWebSocketHandler.java

public class SystemWebSocketHandler implements WebSocketHandler {
private static final Logger logger;
private static final ArrayList<WebSocketSession> users;
static {
users = new ArrayList<>();
logger = LoggerFactory.getLogger(SystemWebSocketHandler.class);
}
@Autowired
private WebSocketService webSocketService;
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
logger.debug("connect to the websocket success......");
users.add(session);
String userName = (String) session.getAttributes().get(Constants.WEBSOCKET_USERNAME);
if(userName!= null){
//查詢未讀消息
int count = webSocketService.getUnReadNews((String) session.getAttributes().get(Constants.WEBSOCKET_USERNAME));
session.sendMessage(new TextMessage(count + ""));
}
}
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
//sendMessageToUsers();
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
if(session.isOpen()){
session.close();
}
logger.debug("websocket connection closed......");
users.remove(session);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
logger.debug("websocket connection closed......");
users.remove(session);
}
@Override
public boolean supportsPartialMessages() {
return false;
}
/**
* 給所有在線用戶發(fā)送消息
*
* @param message
*/
public void sendMessageToUsers(TextMessage message) {
for (WebSocketSession user : users) {
try {
if (user.isOpen()) {
user.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 給某個用戶發(fā)送消息
*
* @param userName
* @param message
*/
public void sendMessageToUser(String userName, TextMessage message) {
for (WebSocketSession user : users) {
if (user.getAttributes().get(Constants.WEBSOCKET_USERNAME).equals(userName)) {
try {
if (user.isOpen()) {
user.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
}

相關(guān)內(nèi)容大家一看就能明白,就不多解釋了

然后WebSocketHandshakeInterceptor.java

public class WebSocketHandshakeInterceptor implements HandshakeInterceptor {
private static Logger logger = LoggerFactory.getLogger(HandshakeInterceptor.class);
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object
> attributes) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
HttpSession session = servletRequest.getServletRequest().getSession(false);
if (session != null) {
//使用userName區(qū)分WebSocketHandler,以便定向發(fā)送消息
String userName = (String) session.getAttribute(Constants.SESSION_USERNAME);
attributes.put(Constants.WEBSOCKET_USERNAME,userName);
}
}
return true;
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
}
}

這個的主要作用是取得當(dāng)前請求中的用戶名,并且保存到當(dāng)前的WebSocketHandler中,以便確定WebSocketHandler所對應(yīng)的用戶,具體可參考HttpSessionHandshakeInterceptor

用戶登錄建立websocket連接

index.jsp

<script type="text/javascript" src="http://localhost:8080/Origami/websocket/sockjs-0.3.min.js"></script>
<script>
var websocket;
if ('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8080/Origami/webSocketServer");
} else if ('MozWebSocket' in window) {
websocket = new MozWebSocket("ws://localhost:8080/Origami/webSocketServer");
} else {
websocket = new SockJS("http://localhost:8080/Origami/sockjs/webSocketServer");
}
websocket.onopen = function (evnt) {
};
websocket.onmessage = function (evnt) {
$("#msgcount").html("(<font color='red'>"+evnt.data+"</font>)")
};
websocket.onerror = function (evnt) {
};
websocket.onclose = function (evnt) {
}
</script>

使用sockjs時要注意

1、這兩個的寫法

<script type="text/javascript" src="http://localhost:8080/Origami/websocket/sockjs-0.3.min.js"></script>
websocket = new SockJS(http://localhost:8080/Origami/sockjs/webSocketServer);

2、web.xml中

<web-app version="3.0" 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_3_1.xsd">

version

web-app_3_1.xsd

這兩個的版本都要是3.0+

然后在這個servlet中加入

<async-supported>true</async-supported>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>

然后所有的filter中也加入

<async-supported>true</async-supported>

3、添加相關(guān)依賴

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.3.3</version>
</dependency>

好了,現(xiàn)在websocket可以正常建立起來了

返回用戶未讀的消息

當(dāng)連接建立后,會進入SystemWebSocketHandler的afterConnectionEstablished方法,代碼看上邊,取出WebSocketHandshakeInterceptor中保存的用戶名

查詢信息后使用session.sendMessage(new TextMessage(count + ""));返回給用戶,從哪來回哪去

服務(wù)端推送消息給用戶

@Controller
public class AdminController {
static Logger logger = LoggerFactory.getLogger(AdminController.class);
@Autowired(required = false)
private AdminService adminService;
@Bean
public SystemWebSocketHandler systemWebSocketHandler() {
return new SystemWebSocketHandler();
}
@RequestMapping("/auditing")
@ResponseBody
public String auditing(HttpServletRequest request){
//無關(guān)代碼都省略了
int unReadNewsCount = adminService.getUnReadNews(username);
systemWebSocketHandler().sendMessageToUser(username, new TextMessage(unReadNewsCount + ""));
return result;
}
}

在這里可以使用sendMessageToUser給某個用戶推送信息,也可以使用sendMessageToUsers給所有用戶推送信息

相關(guān)文章

  • 10分鐘帶你理解Java中的弱引用

    10分鐘帶你理解Java中的弱引用

    這篇文章將帶大家快速理解Java中弱引用,文章介紹的很詳細(xì),對大家學(xué)習(xí)Java很有幫助哦,有需要的可以參考借鑒。
    2016-08-08
  • SpringBoot創(chuàng)建多模塊項目的全過程記錄

    SpringBoot創(chuàng)建多模塊項目的全過程記錄

    這篇文章主要給大家介紹了關(guān)于SpringBoot創(chuàng)建多模塊項目的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • struts2的流程和一系列相關(guān)知識代碼解析

    struts2的流程和一系列相關(guān)知識代碼解析

    這篇文章主要介紹了struts2的流程和一系列相關(guān)知識代碼解析,具有一定借鑒價值,需要的朋友可以參考下。
    2017-12-12
  • Spring?cloud?OpenFeign中動態(tài)URl、動態(tài)傳遞接口地址代碼示例

    Spring?cloud?OpenFeign中動態(tài)URl、動態(tài)傳遞接口地址代碼示例

    openFeign是作為微服務(wù)之間調(diào)用的解決方案,每個微服務(wù)項目是必不可少的,下面這篇文章主要給大家介紹了關(guān)于Spring?cloud?OpenFeign中動態(tài)URl、動態(tài)傳遞接口地址的相關(guān)資料,需要的朋友可以參考下
    2024-02-02
  • springboot啟動后卡住無日志的幾種情況小結(jié)

    springboot啟動后卡住無日志的幾種情況小結(jié)

    這篇文章主要介紹了springboot啟動后卡住無日志的幾種情況小結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 解析MapStruct轉(zhuǎn)換javaBean時出現(xiàn)的詭異事件

    解析MapStruct轉(zhuǎn)換javaBean時出現(xiàn)的詭異事件

    在項目中用到了MapStruct,對其可以轉(zhuǎn)換JavaBean特別好奇,今天小編給大家分享一個demo給大家講解MapStruct轉(zhuǎn)換javaBean時出現(xiàn)的詭異事件,感興趣的朋友一起看看吧
    2021-09-09
  • Java Swing中JList選擇事件監(jiān)聽器ListSelectionListener用法示例

    Java Swing中JList選擇事件監(jiān)聽器ListSelectionListener用法示例

    這篇文章主要介紹了Java Swing中JList選擇事件監(jiān)聽器ListSelectionListener用法,結(jié)合具體實例形式分析了中JList選擇事件監(jiān)聽器ListSelectionListener的功能、使用方法及相關(guān)注意事項,需要的朋友可以參考下
    2017-11-11
  • Springboot使用RabbitMQ實現(xiàn)關(guān)閉超時訂單(示例詳解)

    Springboot使用RabbitMQ實現(xiàn)關(guān)閉超時訂單(示例詳解)

    介紹了如何在Spring Boot項目中使用RabbitMQ實現(xiàn)訂單的延時處理和超時關(guān)閉,通過配置RabbitMQ的交換機、隊列和綁定關(guān)系,以及編寫監(jiān)聽方法,實現(xiàn)了訂單數(shù)據(jù)的發(fā)送和延時消費,感興趣的朋友一起看看吧
    2025-01-01
  • SpringBoot定時任務(wù)實現(xiàn)數(shù)據(jù)同步的方法

    SpringBoot定時任務(wù)實現(xiàn)數(shù)據(jù)同步的方法

    業(yè)務(wù)需求是,通過中臺調(diào)用api接口獲得,設(shè)備數(shù)據(jù),要求現(xiàn)實設(shè)備數(shù)據(jù)的同步,這篇文章主要介紹了SpringBoot定時任務(wù)實現(xiàn)數(shù)據(jù)同步的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 詳解關(guān)于spring bean名稱命名的那些事

    詳解關(guān)于spring bean名稱命名的那些事

    每個bean都有一個或者多個標(biāo)識符,這些標(biāo)識符在容器中必須是唯一的,這篇文章主要給大家介紹了關(guān)于spring bean名稱命名的那些事,需要的朋友可以參考下
    2021-07-07

最新評論

海城市| 松原市| 海兴县| 大城县| 凤山市| 海林市| 江源县| 舟曲县| 上思县| 通榆县| 惠来县| 洛宁县| 宝坻区| 于都县| 静宁县| 保靖县| 故城县| 舒城县| 新津县| 阿鲁科尔沁旗| 磐石市| 桓台县| 顺义区| 郧西县| 祁东县| 济宁市| 石棉县| 吉隆县| 乌兰县| 西城区| 黎平县| 龙山县| 泗洪县| 澄城县| 内江市| 珲春市| 区。| 博罗县| 临沭县| 密云县| 郓城县|