- Websocket使用 ws 或 wss 的統(tǒng)一資源標(biāo)志符,類似于 HTTP 或 HTTPS,其中 wss 表示在 TLS 之上的 Websocket ,相當(dāng)于 HTTPS 了。
- 默認情況下,Websocket 的 ws 協(xié)議使用 80 端口;運行在TLS之上時,wss 協(xié)議默認使用 443 端口。其實說白了,wss 就是 ws 基于 SSL 的安全傳輸,與 HTTPS 一樣樣的道理
配置Nginx支持wss
# 我的配置在https的nginx下面
location /usign {
proxy_pass http://127.0.0.1:9990/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 5000M;
}
代碼中的使用
vue中配置
- 我這里用在了vue里面,工程使用的腳手架。websocket用在了app.vue里面,因為我的是全局的監(jiān)聽。從服務(wù)器上面回來的數(shù)據(jù),可以通過vue的store來改變其他頁面的數(shù)據(jù)
<script>
import { mapState, mapMutations } from 'vuex'
export default {
name: 'App',
data () {
return {
websock: null,
reconnectData: null,
lockReconnect: false,
timeout: 10000,
timeoutObj: null,
serverTimeoutObj: null
}
},
computed: {
...mapState([
'currentUser',
'identificationDevice',
'logshow'
])
},
created () {
document.title = ''
this.initWebSocket()
},
methods: {
...mapMutations([
'updatePromptBtn',
'updateIpaName'
]),
initWebSocket () {
if (this.websock !== null) {
this.websock.close()
this.websock = null
}
let wsurl = ''
if (this.baseUrl.indexOf('192') === -1) {
let url = this.baseUrl.substr(this.baseUrl.indexOf('www'))
wsurl = 'wss://' + url + '/websocket'
} else {
let url = this.baseUrl.substr(this.baseUrl.indexOf('192'))
wsurl = 'ws://' + url + '/websocket'
}
if (this.logshow) {
console.log('啟動中' + wsurl)
}
this.websock = new WebSocket(wsurl)
this.websock.onopen = this.websocketonopen
this.websock.onmessage = this.websocketonmessage
this.websock.onerror = this.websocketonerror
this.websock.onclose = this.websocketclose
},
websocketonopen () {
if (this.logshow) {
console.log('連接成功')
}
this.heartBeat()
},
websocketonerror () {
if (this.logshow) {
console.log('連接失敗')
}
this.reconnect()
},
websocketclose () {
if (this.logshow) {
console.log('斷開連接')
}
this.reconnect()
},
websocketonmessage (msg) {
let data = JSON.parse(msg.data)
if (data.type === 'heartBeat') {
if (this.logshow) {
console.log('收到心跳回復(fù):' + data.type)
}
this.heartBeat()
}
if (this.currentUser === undefined || this.currentUser == null) {
return
}
if (this.identificationDevice !== data.identificationDevice) {
if (this.logshow) {
console.log('收到不是自己的:from', data.identificationDevice)
}
return
}
if (this.logshow) {
console.log('收到消息: ' + msg.data)
}
// 這里定義自己的邏輯
},
websocketsend (data) {
this.websock.send(JSON.stringify(data))
},
reconnect () {
if (this.lockReconnect) {
return
}
this.lockReconnect = true
this.reconnectData && clearTimeout(this.reconnectData)
this.reconnectData = setTimeout(() => {
this.initWebSocket()
this.lockReconnect = false
}, 5000)
},
heartBeat () {
this.timeoutObj && clearTimeout(this.timeoutObj)
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj)
this.timeoutObj = setTimeout(() => {
this.websocketsend({ type: 'heartBeat' })
this.serverTimeoutObj = setTimeout(() => {
this.websock.close()
}, 5000)
}, this.timeout)
}
},
destroyed () {
this.lockReconnect = true
this.websock.close()
clearTimeout(this.reconnectData)
clearTimeout(this.timeoutObj)
clearTimeout(this.serverTimeoutObj)
}
}
</script>
Java中配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
/**
* 開啟WebSocket支持
*/
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
- 3、寫服務(wù)類WebSocketServer
@ServerEndpoint("/websocket")
@Component
public class WebSocketServer extends BaseService{
static Log log=LogFactory.get(WebSocketServer.class);
private static CopyOnWriteArraySet<WebSocketServer> webSocketServers = new CopyOnWriteArraySet<>();
private Session session;
/**
* 連接建立成功調(diào)用的方法*/
@OnOpen
public void onOpen(Session session) {
this.session = session;
webSocketServers.add(this);
try {
sendMessage("與后端連接成功");
} catch (IOException e) {
log.error("網(wǎng)絡(luò)異常!!!!!!");
}
}
/**
* 連接關(guān)閉調(diào)用的方法
*/
@OnClose
public void onClose() {
log.info("連接關(guān)閉");
webSocketServers.remove(this);
}
/**
* 收到客戶端消息后調(diào)用的方法
*
* @param message 客戶端發(fā)送過來的消息*/
@OnMessage
public void onMessage(String message) throws IOException {
log.info("報文:"+message);
JSONObject jsonObject = JSON.parseObject(message);
Object type = jsonObject.get("type");
if (type != null && type.equals("heartBeat")) {
sendMessage(message);
}
}
/**
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("onError原因:"+error.getMessage());
error.printStackTrace();
}
/**
* 實現(xiàn)服務(wù)器主動推送
*/
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
/**
* 發(fā)送自定義消息
* */
public static void sendInfo(Map message) throws IOException {
String msg = JSON.toJSONString(message);
log.info("發(fā)送消息報文:" + msg);
for (WebSocketServer webSocketServer:webSocketServers) {
webSocketServer.sendMessage(msg);
}
}
}
@GetMapping(value = "/update/config")
public RestResponse updateMobileconfig(
@RequestParam String key,
@RequestParam String type,
@RequestParam String identificationDevice
) throws IOException {
Map<String, String> map = new HashMap();
map.put("identificationDevice", identificationDevice);
map.put("key", key);
map.put("type", type);
WebSocketServer.sendInfo(map);
return RestResponse.success();
}
以上都是簡單的使用,如果對你有用這是最好