WebSocket
WebSocket 事HTML5开始提供的一种在单个TCP连接上进行的双工通讯的协议,可以在html页面直接使用。
WebSocket使用客户端何服务器之间的数据交换变得更加简单,允许服务端主动向客户端推动数据。在WebSocketAPI中,浏览器和服务器只需完成一次握手,两者之间直接可以建立持久性的连接,并进行双向数据传输。
1,WebSocket 事件
以下是WebSocket对象的相关事件
事件 | 事件处理程序 | 描述 |
---|---|---|
open | Socket.onopen | 建立连接时触发 |
message | Socket.onmessage | 客户端接受服务器数据时触发 |
error | Socket.onerror | 通讯发生错误是触发 |
close | Socket.onclose | 连接关闭是触发 |
2,WebSocket方法
以下是WebSocket对象的相关方法
方法 | 描述 |
---|---|
Socket.send() | 使用连接发送信息 |
Socket.close() | 关闭连接 |
3,WebSocket聊天室
3.1,引入websocket依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</exclusion>
</exclusions>
</dependency>
3.2,编写websocket工具类
package com.woniu.util;
import javax.websocket.RemoteEndpoint;
import javax.websocket.Session;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class WebSocketUtil {
//放所有参与聊天的用户标识
public static final Map<String, Session> messageMap = new ConcurrentHashMap<>();
/**
*单个消息
*/
public static void send(Session session,String message){
if (session != null){
final RemoteEndpoint.Basic basic = session.getBasicRemote();
if (basic != null){
try {
basic.sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 全体发消息
*/
public static void sendAll(String message){
messageMap.forEach((userName,session) -> send(session,message));
}
}
3.3,编写websocket事件类
package com.woniu.webscoket;
import com.woniu.util.WebSocketUtil;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RestController;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
@RestController
@ServerEndpoint("/WebSocketHandler/{userName}")
public class WebSocketHandler {
@OnOpen
public void openSession(@PathParam("userName") String userName, Session session){
String message = "欢迎:"+userName +"加入群聊";
WebSocketUtil.messageMap.put(userName,session);
//给所有人发消息
WebSocketUtil.sendAll(message);
}
@OnMessage
public void onMessage(@PathParam("userName") String userName, String message){
message = userName +":" +message;
WebSocketUtil.sendAll(message);
}
@OnClose
public void onClose(@PathParam("userName") String userName,Session session){
WebSocketUtil.messageMap.remove(userName);
WebSocketUtil.sendAll("用户:"+userName+"离开聊天室");
try {
session.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.4,编写WebSocketConfig 配置类, 并在启动类上加上 @EnableWebSocket 注解
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
3.5,如果是springsecurity框架需要给websocket配免拦截
//忽略websocket拦截
@Override
public void configure(WebSecurity webSecurity) {
webSecurity.ignoring().antMatchers(
"/WebSocketHandler/**"
);
}
3.6,报错解决
类似:ailed to register @ServerEndpoint class,在test类加上
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
3.7,前端代码
<template>
<div>
<el-row >
<el-col :span="6" :offset="3"> <p style="font-">1号聊天室</p></el-col>
</el-row>
<el-row>
<el-col :span="12" :offset="1"> <textarea id="textarea" disabled="disabled" cols="50" rows="10"></textarea></el-col>
</el-row>
<el-row>
<el-col :span="24">
<span> 用户名:</span>
<span> <el-input type="text" v-model="userName"/></span>
<span> <el-button type="primary" @click="join">加入聊天室</el-button></span>
</el-col>
</el-row>
<el-row>
<el-col :span="4" :offset="1"> <el-input type="text" v-model="message"/> </el-col>
<el-col :span="4" >
<el-button type="success" @click="send">发送</el-button>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
data(){
return{
url:'ws://192.168.2.70:8083/WebSocketHandler/',
ws:'',
userName:'',
message:''
}
},
methods:{
join(){
if(this.userName == ""){
alert("请输入您的大名!")
}
this.ws = new WebSocket(this.url + this.userName);
this.ws.onopen = function(){
console.log("连接成功!")
}
this.ws.onmessage = function(result){
var textarea = document.getElementById("textarea");
textarea.append(result.data+'\n');
textarea.scrollTop = textarea.scrollHeight;
}
this.ws.onclose = function(){
var textarea = document.getElementById("textarea");
textarea.append('用户:'+this.userName+'离开聊天室 \n');
console.log("")
}
},
send(){
if(this.ws != null){
this.ws.send(this.message);
this.message = "";
}
}
}
}
</script>
<style scoped>
p{
font-size: 20px;
color: red;
}
.el-row{
margin:10px 5px;
}
span{
float: left;
}
</style>