什么是webSocket
WebSocket是一种建立在TCP协议之上的通信协议,也称长连接套接字。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。
以下主要分为两个方面来实现,1-服务器后台,2-网页客户端
服务器后台WebSocketServer搭建
- 引入依赖,在此之前我们已经构建好了SpringBoot框架,当然也可以直接在构建SpringBoot框架的时候勾选WebSocket
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
<scope>provided</scope>
</dependency>
- 配置Config类
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
- controller编写
@Controller
public class WebSocketController {
@RequestMapping("/webSocket")
@ResponseBody
public void webSocket(HttpServletRequest request){
String ip = request.getRemoteAddr();
try {
WebSocketServer.sendInfo("有新小伙伴加入了我们"+ip);
} catch (IOException e) {
e.printStackTrace();
}
}
@RequestMapping("/index")
public String index(){
return "index";
}
}
- 核心的WebSocketServer类
/**
* com.qd.ws.controller
*
* @author liyawei
* @date 2018/5/21
*/
@Slf4j
@ServerEndpoint(value = "/webSocket")
@Component
public class WebSocketServer {
// 当前客户端连接数
private static int onlineCount = 0;
// 线程安全Set,用来存放每个客户端对应的MyWebSocket对象
private static CopyOnWriteArraySet<WebSocketServer> webSocket = new CopyOnWriteArraySet<WebSocketServer>();
private Session session;
@OnOpen
public void onOpen(Session session) {
this.session = session;
webSocket.add(this);
addCount();
log.info("有新的小伙伴加入,目前连接数:" + onlineCount);
try {
sendMessage("连接成功,欢迎回来");
} catch (Exception e) {
e.printStackTrace();
}
}
@OnClose
public void onClose() {
webSocket.remove(this);
subCount();
log.info("又一位小伙伴失去了梦想,目前连接数:" + onlineCount);
}
@OnMessage
public void onMessage(String message, Session session) {
log.info("收到消息:" + message);
try {
sendInfo(message);
} catch (IOException e) {
e.printStackTrace();
log.error("消息发送失败");
}
}
@OnError
public void onError(Session session, Throwable throwable) {
log.error("发生错误");
throwable.printStackTrace();
}
/**
* 发送消息
*
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
public static void sendInfo(String message) throws IOException {
log.info(message);
for (WebSocketServer webSocketServer : webSocket) {
try {
webSocketServer.sendMessage(message);
} catch (IOException e) {
// 如果有发送失败的继续发送下一个
continue;
}
}
}
public static synchronized Integer getCount(){
return onlineCount;
}
public static synchronized void addCount() {
onlineCount++;
}
public static synchronized void subCount() {
onlineCount--;
}
}
H5客户端实现
这里需要在application.properties或yml中配置一下web页面配置,这样可以让controller直接返回html页面,当然你也可以用使用模板引擎
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>QD聊天室</title>
</head>
<body>
<div>
<input type="text" id="sendMessage">
<button type="button" onclick="send()">发送</button>
<div id="getMessage"></div>
<script type="text/javascript">
// 判断当前浏览器是否支持webSocket
webSocket = new WebSocket("ws://localhost:8089/webSocket");
webSocket.onopen = function (ev) {
alert("欢迎回来");
};
webSocket.onclose = function (ev) {
alert("88");
};
webSocket.onmessage = function (ev) {
displayMessage(ev.data);
};
function displayMessage(innerHTML) {
document.getElementById('getMessage').innerHTML += innerHTML+'<br/>';
}
function close() {
webSocket.close();
}
function send() {
var sendMessage = document.getElementById('sendMessage').value;
webSocket.send(sendMessage);
}
</script>
</div>
</body>
</html>
页面效果,不要在意这些细节。。
客户端发送消息和服务器后台