前言:最近開發(fā)公司的一個(gè)會(huì)員卡,酒店預(yù)訂房間的功能,考慮到要實(shí)現(xiàn)后臺(tái)管理的訂單提示,所以在項(xiàng)目中引用websocket,事實(shí)上在spring boot中引入webSocket 還是非常簡(jiǎn)單的,但是我還是爬了很多坑,在此記錄一下希望可以幫助一些可能同樣會(huì)爬坑的同學(xué)。 1:jar包的引入,只引這個(gè)的前提是使用tomcat7.0以上的版本,我用的是tomcat8,所以用這個(gè)就夠了,若是低版本的還需引入javaee-api。
2:配置文件,這里要注意一下,使用springboot的內(nèi)置tomcat運(yùn)行和打war包發(fā)布到外部Tomcat運(yùn)行時(shí)配置是不一樣的。 1.先創(chuàng)建一個(gè)WebSocketConfig.java 2.使用spring boot內(nèi)置tomcat運(yùn)行時(shí)的配置。
這里的配置是ServerEndpointExporter的注入,配置該出會(huì)為我們后面使用到@ServerEndPoint注解的地方自動(dòng)注冊(cè)Websocket endpoint。 3.使用外部的tomcat發(fā)布時(shí) WebSocketConfig.java 中就不需要 ServerEndpointExporter 的注入,因?yàn)檫@是它是由外部容器自己提供和管理的,如果你在使用外部容器發(fā)布時(shí)注入這個(gè)bean,項(xiàng)目啟動(dòng)的時(shí)候會(huì)報(bào) javax.websocket.DeploymentException: Multiple Endpoints may not be deployed to the same path xxxx錯(cuò)誤,別問(wèn)我是怎么知道的(/"≡ _ ≡)/~┴┴。 所以這個(gè)時(shí)候的配置是這樣的:
3:上面都配置好后我們就來(lái)看websocket使用的重頭戲@ServerEndpoint的使用,前面有說(shuō)。之前的配置就是為了是項(xiàng)目能在使用了注解的地方自動(dòng)注冊(cè)Websocket endpoint,在這里我們就能實(shí)現(xiàn)websocket的鏈接、關(guān)閉、發(fā)送和接收消息的操作,這文件看起來(lái)有點(diǎn)像controller,但又有些不同,所以我就把他放在service層了這個(gè)有參考慕課網(wǎng)廖師兄的操作。 1.創(chuàng)建一個(gè)WebSocket.java。
@OnOpen:在前端訪問(wèn)websocket時(shí)開一個(gè)新的連接。這里有用一個(gè)集合來(lái)記錄連接,方便查看管理; @OnClose:斷開連接; @OnMessage:接收消息接口; sendMessage:發(fā)送消息的接口; 到目前為止服務(wù)端的準(zhǔn)備就做好了。 現(xiàn)在開始前端調(diào)用,這里使用的是原生Html5來(lái)調(diào)用如下:
其實(shí)這里和上面ServerEndpoint一樣,想必大家也是見文知意。 無(wú)非是初始化一個(gè)Websocket,創(chuàng)建連接,關(guān)閉連接,接收消息,發(fā)送消息,這些就不多說(shuō)了,主要在這里說(shuō)一下幾個(gè)需要注意的點(diǎn)。 1:初始化時(shí) new WebSocket(wsUrl ); 這個(gè)url就是請(qǐng)求連接@ServerEndpoint配置的地方,所以說(shuō)它的使用時(shí)候是不是有點(diǎn)像Controller的使用,拿上面的請(qǐng)求路徑做個(gè)說(shuō)明: var wsUrl = "ws://localhost:8008/webSocketTest/webSocket"; ws:是websocket的協(xié)議,websocket用的不是http協(xié)議,這里我就不對(duì)這兩個(gè)協(xié)議的區(qū)別做詳細(xì)的說(shuō)明,有興趣自己搜一下。需要注意的是如果請(qǐng)求頭的是http的就用ws,若請(qǐng)求的是https則使用wss。 localhost:就是服務(wù)的ip或域名。 8008:端口號(hào)。 webSocketTest:發(fā)布的項(xiàng)目名。 webSocket:@ServerEndpoint中配置的路徑。 2.websocket長(zhǎng)連接有默認(rèn)的超時(shí)時(shí)間(proxy_read_timeout),就是超過(guò)一定的時(shí)間沒(méi)有發(fā)送任何消息,連接會(huì)自動(dòng)斷開。所以我們要想保持長(zhǎng)連接可以使用心跳包,定時(shí)像服務(wù)器發(fā)送心跳保持通信,上面的js中就有使用,當(dāng)發(fā)生錯(cuò)誤或斷開連接時(shí)我們可以重新連接。 3.最后再提醒一下,如果項(xiàng)目部署到線上是使用了Nginx代理,一定要記得在Nginx配置websocket,前面有說(shuō)過(guò)wesocket使用的不是http協(xié)議,如果你用了Nginx又沒(méi)有配置websocket的話,前端初始化websocket就會(huì)報(bào)404。 下面引用其他博主的一個(gè)解決方案,具體參考:springboot + websocket + linux服務(wù)器(nginx)404問(wèn)題解決 配置nginx反向代理響應(yīng)webSocket請(qǐng)求 需要在代理的請(qǐng)求配置中加入下面的配置:
Nginx配置
|
|
來(lái)自: jackeyqing > 《websocket》