增加项目说明

This commit is contained in:
罗祥
2019-01-08 17:02:55 +08:00
parent f1594c6de7
commit 48039923fe
61 changed files with 3345 additions and 100 deletions

View File

@ -0,0 +1,183 @@
# spring boot websocket
## 一、说明
### 1.1 项目结构说明
1. 项目模拟一个简单的群聊功能为区分不同的聊天客户端登录时候将临时用户名存储在session当中
2. 关于websocket的主要配置在websocket文件夹下
3. 模板引擎采用freemaker
4. 项目以web的方式构建。
![spring-scheduling](D:\spring-samples-for-all\pictures\spring-boot-websocket.png)
### 1.2 主要依赖
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--spring boot webSocket 的依赖包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
```
## 二、spring boot websocket
#### 2.1 创建消息处理类ChatSocket使用@ServerEndpoint声明websocket服务
```java
@ServerEndpoint(value = "/socket/{username}")
@Component
public class ChatSocket {
/**
* 建立连接时候触发
*/
@OnOpen
public void onOpen(Session session, @PathParam("username") String username) {
// 这个方法是线程不安全的
Constant.nameAndSession.putIfAbsent(username, session);
}
/**
* 关闭连接时候触发
*/
@OnClose
public void onClose(Session session, @PathParam("username") String username) {
Constant.nameAndSession.remove(username);
}
/**
* 处理消息
*/
@OnMessage
public void onMessage(Session session, String message, @PathParam("username") String username) throws UnsupportedEncodingException {
// 防止中文乱码
String msg = URLDecoder.decode(message, "utf-8");
// 简单模拟群发消息
Constant.nameAndSession.forEach((s, webSocketSession)
-> {
try {
webSocketSession.getBasicRemote().sendText(username + " : " + msg);
} catch (IOException e) {
e.printStackTrace();
}
});
}
}
```
#### 2.2 配置ServerEndpointExporterServerEndpointExporter会在运行时候自动注册我们用@ServerEndpoint声明的websocket服务。
```java
@Configuration
public class WebSocketConfig {
/***
* 检测{@link javax.websocket.server.ServerEndpointConfig}和{@link ServerEndpoint} 类型的bean
* 并在运行时使用标准Java WebSocket时注册。
* 我们在{@link com.heibaiying.springboot.websocket.WebSocketConfig}中就是使用@ServerEndpoint去声明websocket服务
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
```
#### 2.3 前端websocket的实现
```jsp
<!doctype html>
<html lang="en">
<head>
<title>${Session["username"]}您好!欢迎进入群聊大厅!</title>
</head>
<body>
<h5>${Session["username"]}您好!欢迎进入群聊大厅!</h5>
<input id="message" type="text">
<button id="btn">发送消息</button>
<div id="show">
</div>
<script>
let btn = document.getElementById("btn");
let message = document.getElementById("message");
let show = document.getElementById("show");
let ws = new WebSocket("ws://localhost:8080/socket/${Session["username"]}");
ws.onmessage = function (evt) {
let node = document.createElement("div");
node.innerHTML = "<h5>" + evt.data + "</h5>";
show.appendChild(node);
};
btn.addEventListener("click", function () {
let data = message.value;
console.log(data);
if (data) {
ws.send(encodeURI(data));
} else {
alert("请输入消息后发送");
}
message.value = "";
});
// 关闭页面时候关闭ws
window.addEventListener("beforeunload", function (event) {
ws.close();
});
</script>
</body>
</html>
```
#### 2.4 简单登录的实现
```java
<!doctype html>
<html lang="en">
<head>
<title>Title</title>
</head>
<body>
<form action="/login" method="post">
<input name="username" type="text">
<button id="btn">输入临时用户名后登录</button>
</form>
</body>
</html>
```
```java
/**
* @description : 简单登录
*/
@Controller
public class LoginController {
@PostMapping("login")
public String login(String username, HttpSession session) {
session.setAttribute(Constant.USER_NAME, username);
return "chat";
}
@GetMapping
public String index() {
return "index";
}
}
```

View File

@ -4,11 +4,7 @@ import javax.websocket.Session;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author : 罗祥
* @description :
* @date :create in 2018/12/27
*/
public interface Constant {
String USER_NAME="username";

View File

@ -8,9 +8,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import javax.servlet.http.HttpSession;
/**
* @author : 罗祥
* @description : 简单登录
* @date :create in 2018/12/27
*/
@Controller
public class LoginController {

View File

@ -21,20 +21,28 @@ import java.net.URLDecoder;
@Component
public class ChatSocket {
@OnOpen //建立连接时候触发
/**
* 建立连接时候触发
*/
@OnOpen
public void onOpen(Session session, @PathParam("username") String username) {
// 这个方法是线程不安全的
Constant.nameAndSession.putIfAbsent(username, session);
}
@OnClose //关闭连接时候触发
/**
* 关闭连接时候触发
*/
@OnClose
public void onClose(Session session, @PathParam("username") String username) {
Constant.nameAndSession.remove(username);
}
@OnMessage //处理消息
/**
* 处理消息
*/
@OnMessage
public void onMessage(Session session, String message, @PathParam("username") String username) throws UnsupportedEncodingException {
// 防止中文乱码
String msg = URLDecoder.decode(message, "utf-8");

View File

@ -4,12 +4,19 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
import javax.websocket.server.ServerEndpoint;
/**
* @author : heibaiying
*/
@Configuration
public class WebSocketConfig {
/***
* 检测{@link javax.websocket.server.ServerEndpointConfig}和{@link ServerEndpoint} 类型的bean
* 并在运行时使用标准Java WebSocket时注册。
* 我们在{@link com.heibaiying.springboot.websocket.WebSocketConfig}中就是使用@ServerEndpoint去声明websocket服务
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();