摘要:子協(xié)議只是一個(gè)消息傳遞的體系結(jié)構(gòu),沒(méi)有指定任何的消息傳遞協(xié)議。是一個(gè)簡(jiǎn)單的消息傳遞協(xié)議,是一種為,面向消息的中間件設(shè)計(jì)的簡(jiǎn)單文本協(xié)議。的實(shí)現(xiàn)對(duì)內(nèi)嵌的或者和使用了提供了支持。廣播式廣播式即服務(wù)端有消息時(shí),會(huì)將消息發(fā)送到所有連接了當(dāng)前的瀏覽器。
簡(jiǎn)單介紹
WebSocket是為瀏覽器和服務(wù)端提供雙工藝部通信功能一種工具,即瀏覽器可以先服務(wù)端發(fā)送消息,服務(wù)端也可以先瀏覽器發(fā)送消息。現(xiàn)在支持Websocket的瀏覽器有 IE10+,Crome13+,F(xiàn)ileFox6+。
WebSocket子協(xié)議WebSocket只是一個(gè)消息傳遞的體系結(jié)構(gòu),沒(méi)有指定任何的消息傳遞協(xié)議。與HTTP協(xié)議不同的是,WebSocket只是一個(gè)應(yīng)用層的協(xié)議,它非常簡(jiǎn)單,并不能理解傳入的消息,也不能對(duì)消息進(jìn)行路由或處理,因此WebSocket協(xié)議只是一個(gè)應(yīng)用層的協(xié)議,其上需要一個(gè)框架來(lái)理解和處理消息。
Spring框架提供了對(duì)使用STOMP子協(xié)議的支持。STOMP,全稱Streaming Text Orientated Message Protol,流文本定向協(xié)議。STOMP是一個(gè)簡(jiǎn)單的消息傳遞協(xié)議,是一種為MOM(Message Orientated Middleware,面向消息的中間件)設(shè)計(jì)的簡(jiǎn)單文本協(xié)議。STOMP提供了一個(gè)可操作的連接格式,允許STOMP客戶端與任意代理(Broker)進(jìn)行交互,類似于OpenWire(一種二進(jìn)制協(xié)議)。
Spring Boot的WebSocket實(shí)現(xiàn)
SpringBoot對(duì)內(nèi)嵌的Tomcat(7或者8)、Jetty9和Undertow使用了WebSocket提供了支持。
廣播式廣播式即服務(wù)端有消息時(shí),會(huì)將消息發(fā)送到所有連接了當(dāng)前endpoint的瀏覽器。
配置WebSocket需要在配置類上使用@EnableWebSocketMessageBroker開(kāi)啟WebSocket支持,并通過(guò)集成AbstractWebSocketMessageBrokerConfigurer類,重寫(xiě)其方法來(lái)配置WebSocket。
package com.example.config; import org.springframework.context.annotation.Configuration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer; import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.StompEndpointRegistry; /** * Created by lenovo on 2017/3/15. */ @Configuration @EnableWebSocketMessageBroker //通過(guò)@EnableWebSocketMessageBroker 注解凱旗使用STOMP協(xié)議來(lái)傳輸基于代理(message broker)的消息 //這時(shí)控制器支持使用@MessageMapping,就像使用@RequestMapping一樣 public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{ @Override public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) { stompEndpointRegistry.addEndpoint("/endpoint").withSockJS();//注冊(cè)STOMP協(xié)議的節(jié)點(diǎn),映射指定的URL,并指定使用SockJS協(xié)議 } @Override public void configureMessageBroker(MessageBrokerRegistry registry) {//配置消息代碼(Message Broker) registry.enableSimpleBroker("/topic");//廣播式應(yīng)配置一個(gè)/topic消息代理 } }
消息的接收器、發(fā)送器和控制器
package com.example.model; /** * Created by lenovo on 2017/3/15. */ public class MessageSender { private String msg; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public MessageSender(String msg) { this.msg = msg; } }
package com.example.model; import java.io.Serializable; /** * Created by lenovo on 2017/3/15. */ public class MessageAcceptor implements Serializable{ private String msg; public String getMsg() { return msg; } }
package com.example.websocket; import com.example.model.MessageAcceptor; import com.example.model.MessageSender; import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * Created by lenovo on 2017/3/15. */ @Controller public class TestWeb { @MessageMapping(value = "/message/test")//當(dāng)瀏覽器向服務(wù)端發(fā)送請(qǐng)求時(shí),通過(guò)@MessageMapping映射的地址,類似于@RequestMapping @SendTo(value = "/topic/response")//當(dāng)服務(wù)端有消息時(shí),會(huì)對(duì)訂閱了@SendTo中的路徑的瀏覽器發(fā)送消息 public MessageSender say(MessageAcceptor acceptor){ return new MessageSender("HELLO!"+acceptor.getMsg()); } @RequestMapping("index") public String index(){ return "index"; } }準(zhǔn)備 WebSocket需要的前端文件。
下載stomp.min.js和sockjs.min.js文件,并放在static下,然后在templates下新建index.html頁(yè)面
stomp的API參考鏈接:https://segmentfault.com/a/11...
上述代碼都已經(jīng)準(zhǔn)備好了,那么一起來(lái)看一看運(yùn)行效果Title
如預(yù)期一樣,在連接了WebSocket的客戶端發(fā)送消息時(shí),其它同樣連接了WebSocket的客戶端瀏覽器也收到了消息,沒(méi)有連接WebSocket的客戶端則沒(méi)有收到消息
看完了代碼和代碼的運(yùn)行效果,我們?cè)賮?lái)看一看WebSocket運(yùn)行中STOMP的幀連接STOMP服務(wù)端幀:CONNECT?accept-version:1.1,1.0?heart-beat:10000,10000 連接STOMP服務(wù)端成功幀:CONNECTED?version:1.1?heart-beat:0,0 訂閱目標(biāo)/topic/response:SUBSCRIBE?id:sub-0?destination:/topic/response 向目標(biāo)/message/test發(fā)送消息:SEND?destination:/message/test?content-length:16??{"msg":"測(cè)試"} 從目標(biāo)/topic/response接收到消息:MESSAGE?destination:/topic/response?content-type:application/json;charset=UTF-8?subscription:sub-0?message-id:hstpp2xl-0?content-length:22??{"msg":"HELLO!測(cè)試"}點(diǎn)對(duì)點(diǎn)式
廣播式有自己的應(yīng)用場(chǎng)景,但是廣播式不能解決我們我們一個(gè)常見(jiàn)的問(wèn)題,即消息由誰(shuí)發(fā)送,由誰(shuí)接受的問(wèn)題。
1.在進(jìn)行點(diǎn)對(duì)點(diǎn)傳遞消息的時(shí)候,必然發(fā)生在兩個(gè)用戶之間的行為,那么就需要添加用戶相關(guān)的內(nèi)容,在這里先完成一個(gè)簡(jiǎn)單的登陸。
首先添加Spring Security的starter pom:
org.springframework.boot spring-boot-starter-security
2.然后進(jìn)行spring security的簡(jiǎn)單配置
package com.example.config; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; /** * Created by lenovo on 2017/3/17. */ @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { /** * 權(quán)限管理配置構(gòu)造器 * * @param auth 權(quán)限管理 * @throws Exception */ @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //配置了兩個(gè)用戶和對(duì)應(yīng)的密碼,并且申明了他們的角色 auth.inMemoryAuthentication().withUser("muxiao").password("123456").roles("USER") .and().withUser("hahaha").password("123456").roles("USER");//在內(nèi)存中分別配置兩個(gè)用戶muxiao和hahaha } /** * Web安全配置 * @param web * @throws Exception */ @Override public void configure(WebSecurity web) throws Exception { //靜態(tài)資源不做安全校驗(yàn) web.ignoring().antMatchers("/resources/static/**");///resources/static/目錄下的靜態(tài)資源,不攔截 } /** * 配置http安全 * @param http * @throws Exception */ @Override protected void configure(HttpSecurity http) throws Exception { //簡(jiǎn)單的配置運(yùn)行點(diǎn)對(duì)點(diǎn)所需要的登陸權(quán)限 http.authorizeRequests() .antMatchers("/","login").permitAll()//設(shè)置Spring Security對(duì)/和/login路徑不攔截 .anyRequest().authenticated() .and().formLogin().loginPage("/login")//設(shè)置登錄頁(yè)面訪問(wèn)的路徑為/login .defaultSuccessUrl("/chat").permitAll()//登陸成功后轉(zhuǎn)向chat頁(yè)面 .and().logout().permitAll(); } } 然后在TestWeb中增加一個(gè)MessageMapping接口: @Autowired private SimpMessagingTemplate messagingTemplate;//spring實(shí)現(xiàn)的一個(gè)發(fā)送模板類 @MessageMapping("/chat") public void handlerChat(Principal principal, String msg) {//springmvc中可以直接在參數(shù)中獲得pricipal,pricipal中包含當(dāng)前永不的信息 if (principal.getName().equalsIgnoreCase("muxiao")) { messagingTemplate.convertAndSendToUser("hahaha","/queue/notice",principal.getName()+":"+msg); } else { messagingTemplate.convertAndSendToUser("muxiao","/queue/notice",principal.getName()+":"+msg); //通過(guò)messaginTemplate.converAndSendTiUser向用戶發(fā)送消息,第一次參數(shù)是接受信息的用戶,第二個(gè)是瀏覽器訂閱的地址,第三個(gè)是消息本身 } }
3.同時(shí)定義需要的頁(yè)面訪問(wèn)路徑:
package com.example.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; /** * Created by lenovo on 2017/3/17. */ @Configuration public class WebViewConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/chat").setViewName("/chat"); registry.addViewController("/login").setViewName("/login"); } }
4.我們已經(jīng)準(zhǔn)備好了所需要的后臺(tái),這時(shí)候就開(kāi)始實(shí)現(xiàn)我們需要的功能的前端編寫(xiě)了。
首先,實(shí)現(xiàn)登陸頁(yè)面,在瀏覽器中訪問(wèn)除過(guò)"/","/index"之外的其它頁(yè)面,都會(huì)來(lái)到login頁(yè)面以進(jìn)行登陸,即下面的頁(yè)面:
輸入我們?cè)趦?nèi)存中指定的用戶名和密碼,登陸進(jìn)入chat頁(yè)面Title
同時(shí)在兩個(gè)瀏覽器上面,用在內(nèi)存中指定的兩個(gè)用戶登陸,這樣兩個(gè)用戶就可以互相發(fā)送消息了,延時(shí)效果如下:
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/89910.html
摘要:作為微服務(wù)的基礎(chǔ)設(shè)施之一,背靠強(qiáng)大的生態(tài)社區(qū),支撐技術(shù)體系。微服務(wù)實(shí)踐為系列講座,專題直播節(jié),時(shí)長(zhǎng)高達(dá)小時(shí),包括目前最流行技術(shù),深入源碼分析,授人以漁的方式,幫助初學(xué)者深入淺出地掌握,為高階從業(yè)人員拋磚引玉。 簡(jiǎn)介 目前業(yè)界最流行的微服務(wù)架構(gòu)正在或者已被各種規(guī)模的互聯(lián)網(wǎng)公司廣泛接受和認(rèn)可,業(yè)已成為互聯(lián)網(wǎng)開(kāi)發(fā)人員必備技術(shù)。無(wú)論是互聯(lián)網(wǎng)、云計(jì)算還是大數(shù)據(jù),Java平臺(tái)已成為全棧的生態(tài)體系,...
摘要:使用則需要及以上版本。開(kāi)發(fā)使用框架七系列教程目錄系列教程大綱快速入門(mén)實(shí)踐實(shí)踐整合整合中和實(shí)踐整合中實(shí)現(xiàn)緩存中實(shí)現(xiàn)通信集成測(cè)試及部署實(shí)戰(zhàn)圖書(shū)管理系統(tǒng) WebFlux 系列教程大綱 一、背景 大家都知道,Spring Framework 是 Java/Spring 應(yīng)用程序跨平臺(tái)開(kāi)發(fā)框架,也是 Java EE(Java Enterprise Edition) 輕量級(jí)框架,其 Spring ...
摘要:開(kāi)公眾號(hào)差不多兩年了,有不少原創(chuàng)教程,當(dāng)原創(chuàng)越來(lái)越多時(shí),大家搜索起來(lái)就很不方便,因此做了一個(gè)索引幫助大家快速找到需要的文章系列處理登錄請(qǐng)求前后端分離一使用完美處理權(quán)限問(wèn)題前后端分離二使用完美處理權(quán)限問(wèn)題前后端分離三中密碼加鹽與中異常統(tǒng)一處理 開(kāi)公眾號(hào)差不多兩年了,有不少原創(chuàng)教程,當(dāng)原創(chuàng)越來(lái)越多時(shí),大家搜索起來(lái)就很不方便,因此做了一個(gè)索引幫助大家快速找到需要的文章! Spring Boo...
閱讀 1643·2021-09-22 15:25
閱讀 1521·2021-09-07 10:06
閱讀 3196·2019-08-30 15:53
閱讀 1100·2019-08-29 13:12
閱讀 3392·2019-08-29 13:07
閱讀 741·2019-08-28 18:19
閱讀 2281·2019-08-27 10:57
閱讀 997·2019-08-26 13:29