太原建站模板,dede网站wap,湖南建筑信息网官网,网站如何留住客户一#xff1a;系统展示: 二#xff1a;约定前后端接口
2.1 登陆
登陆请求#xff1a;
GET /login HTTP/1.1
Content-Type: application/x-www-form-urlencodedusernamezhangsanpassword123登陆响应#xff1a;
正常对象#xff1a;正常对象会在数据库中存储…一系统展示: 二约定前后端接口
2.1 登陆
登陆请求
GET /login HTTP/1.1
Content-Type: application/x-www-form-urlencodedusernamezhangsanpassword123登陆响应
正常对象正常对象会在数据库中存储直接从数据库中取出即可无需通过 set 方法进行设置
HTTP/1.1 200 OK
Content-Type: application/json{userid: 1,username: zhangsan,password: 123,score: 1000,totalcount: 0,wincount: 0
}登陆失败返回空对象
HTTP/1.1 200 OK
Content-Type: application/json{userid: 0,username: null,score: 0,totalcount: 0,wincount: 0
}2.2 注册
注册请求
GET /register HTTP/1.1
Content-Type: application/x-www-form-urlencodedusernamezhangsanpassword123注册响应
HTTP/1.1 200 OK
Content-Type: application/json{userid: 1,username: zhangsan,password: 123,score: 1000,totalcount: 0,wincount: 0
}获取当前用户信息
GET /userinfo HTTP/1.1
Content-Type: application/json{userid: 1,username: zhangsan,score: 1000,totalcount: 0,wincount: 0
}2.2 匹配
匹配请求
ws://127.0.1:8080/Match{message: startMatch / ”stopMatch“ //startMatch 代表开始匹配stopMatch 代表停止匹配
}请求不必带有用户的信息。因为在登陆成功后会把用户信息保存在 httpsession 中websocket 可以拿到这个 httpseesion中存储的数据。
匹配响应 1
ws://127.0.0.1:8080/Match{ok: true, // 进入成功为 true 匹配成功否则为 falsereason: 失败原因, // 失败原因若匹配失败则返回此字段message: startMatch / stopMatch/matchSuccess/repeatConnection //startMatch 代表开始匹配stopMatch 代表停止匹配 ,matchSuccess 代表匹配成功 ,repeatConnection 代表用户多开
}
2.3 对战
对战和匹配使用两套逻辑使用不同的 websocket 路径处理能够更好的解耦合
响应 1 gameready
{message: gameReady,ok: true, // 匹配成功为 true否则为 falsefalse 代表有某些问题reason: , // 出错原因若匹配失败则返回此字段roomid: 123456, // 房间 IDthisuserid: 1, // 自己的用户 IDthatuserid: 2, // 对手的用户 IDwhiteuser: 1 // 先手玩家 ID1 表示自己先2 表示对手先
}
这个请求是玩家匹配成功后由服务器生成的内容把这个内容返回给浏览器
下棋请求 1
{message: putChess,userid: 1,row: 0,col: 0
}下棋响应
{message: putChess,userid: 1,row: 0, // 行col: 0, // 列winner: 0 // 当前是否分出胜负0 代表无胜负非 0 代表获胜方用户 ID
}三 websocket 前置知识
对于 http 来说能够实现客户端向服务器发送数据但是很难实现服务器向客户端发送数据虽然可以通过轮转实现但是这种实现太消耗cpu性能也不好而且实现起来也比较麻烦所以我们选择使用 websocket 协议websocket 协议能实现客户端和服务器的双向通信符合我们目前的需求场景。
WebSocket 与 HTTP 的区别
持久连接WebSocket 连接建立后会一直保持直到显式关闭减少了多次连接开销。双向通信WebSocket 支持全双工通信即客户端和服务器可以在任意时间发送消息。低延迟WebSocket 的头部信息少通信延迟低非常适合实时性要求高的应用场景。
使用 WebSocket 的场景
实时聊天系统如在线客服、聊天应用在线游戏如棋类对战、竞技游戏实时数据推送如股票行情、天气更新、体育比分
3.1 websocket 连接流程
使用 WebSocket 连接的步骤
后端配置 WebSocket 端点定义 WebSocket 端点的 URL客户端通过该 URL 连接到服务器。实现 TextWebSocketHandler 类处理 WebSocket 连接事件包括连接建立、接收消息、连接关闭等。前端建立 WebSocket 连接前端使用 JavaScript 创建 WebSocket 连接发送和接收消息。 步骤一
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;Configuration
EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(new ChatHandler(), /chat); // 将 /chat 端点与 ChatHandler 绑定}
}/chat这是客户端连接的 WebSocket URL端点。ChatHandler我们自定义的 WebSocket 处理器用来处理 WebSocket 的事件。 步骤 2实现 TextWebSocketHandler 类
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;public class ChatHandler extends TextWebSocketHandler {//TextWebSocketHandler 是 Spring 提供的一个辅助类用于处理 WebSocket 的文本消息。// 1. 连接建立时调用Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {System.out.println(连接已建立 session.getId());}// 2. 接收到消息时调用Overrideprotected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {System.out.println(收到消息 message.getPayload());// 将收到的消息返回给客户端session.sendMessage(new TextMessage(服务器响应 message.getPayload()));}// 3. 连接关闭时调用Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {System.out.println(连接已关闭 session.getId());}// 4. 处理错误时调用Overridepublic void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {System.err.println(传输错误 exception.getMessage());}
}afterConnectionEstablished当客户端成功连接时调用比如用户打开 WebSocket 页面。这时候我们可以进行一些初始化操作。handleTextMessage当服务器接收到客户端发送的消息时调用。这里我们简单地把接收到的消息再发送回客户端。afterConnectionClosed当 WebSocket 连接关闭时调用比如用户关闭页面或断开连接。我们可以在这里进行一些清理操作。handleTransportError当连接出错时调用例如网络故障。可以在这里记录错误日志或进行错误处理。 步骤三前端实现
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleWebSocket 示例/title
/head
bodyh2WebSocket 简单示例/h2divinput typetext idmessageInput placeholder输入消息button onclicksendMessage()发送消息/button/divdiv idresponse/divscript// 1. 创建 WebSocket 连接let websocket new WebSocket(ws:// location.host /chat);//建立连接// 2. 连接建立时调用websocket.onopen function() {console.log(WebSocket 连接已建立);};// 3. 接收消息时调用websocket.onmessage function(event) {console.log(收到消息 event.data);document.getElementById(response).innerText 服务器 event.data;};// 4. 连接关闭时调用websocket.onclose function() {console.log(WebSocket 连接已关闭);};// 5. 出错时调用websocket.onerror function(error) {console.error(WebSocket 出现错误 error);};// 发送消息给服务器function sendMessage() {let message document.getElementById(messageInput).value;websocket.send(message); // 发送消息}/script
/body
/html
new WebSocket(“ws://” location.host “/chat”)创建 WebSocket 连接到服务器 /chat 端点绑定的 WebSocket 处理器上。onopen当连接成功时调用可以在这里通知用户连接已建立。onmessage当接收到服务器发送的消息时调用。我们将接收到的消息显示在页面上。onclose当连接关闭时调用可以在这里通知用户连接已关闭。onerror当连接出错时调用。
通过这三个步骤就可以把特定的前端页面和特定的后端类进行连接并通信了
3.2 客户端和服务器互发数据
在 WebSocket 通信中客户端和服务器都可以通过特定的方法发送数据。
3.2.1 客户端发送数据给服务器
在前端客户端使用 WebSocket.send() 方法向服务器发送数据。
// 假设已经创建了 WebSocket 连接
let websocket new WebSocket(ws:// location.host /chat);// 定义一个函数通过 WebSocket 向服务器发送消息
function sendMessage() {let message document.getElementById(messageInput).value; // 获取输入框中的消息websocket.send(message); // 使用 send 方法发送消息给服务器console.log(发送消息给服务器 message);
}3.2.2 服务器发送数据给客户端
在 Spring Boot 中服务器使用 WebSocketSession.sendMessage() 方法向客户端发送数据。
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;public class ChatHandler extends TextWebSocketHandler {Overrideprotected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {System.out.println(收到客户端消息 message.getPayload());// 构造服务器的响应消息TextMessage responseMessage new TextMessage(服务器响应 message.getPayload());// 发送响应消息给客户端session.sendMessage(responseMessage);System.out.println(发送消息给客户端 responseMessage.getPayload());}
}数据通过 sendMessage 发送数据后前端会调用 onmessage 方法 3.3 Json数据 Java对象 JS对象的互相转换
在 Web 开发中我们经常需要在客户端JavaScript和服务器端Java之间传递数据通常会使用 JSON 格式。以下是 JSON 字符串与 JavaScript 对象、Java 对象之间的互相转换方法。
在前端前端需要 JS 对象而在后端后端需要 Java 对象而他们传输的数据都是 Json 格式的数据所以当我们传输数据的时候就涉及到了这三个对象的互相转换
前端发送数据JavaScript 对象 → JSON 字符串 → 发送给后端。后端接收数据JSON 字符串 → Java 对象 → 处理。后端返回数据Java 对象 → JSON 字符串 → 发送给前端。前端接收数据JSON 字符串 → JavaScript 对象 → 处理。
3.3.1 JSON 字符串与 JavaScript 对象的转换
3.3.1.1 JavaScript 对象转为 JSON 字符串
使用 JSON.stringify() 方法将 JavaScript 对象转换为 JSON 字符串。
let jsObject {name: 张三,age: 25,city: 北京
};// 将 JavaScript 对象转换为 JSON 字符串
let jsonString JSON.stringify(jsObject);
console.log(jsonString);
// 输出: {name:张三,age:25,city:北京}3.3.3.2 JSON 字符串转为 JavaScript 对象
使用 JSON.parse() 方法将 JSON 字符串转换为 JavaScript 对象。
let jsonString {name:张三,age:25,city:北京};// 将 JSON 字符串转换为 JavaScript 对象
let jsObject JSON.parse(jsonString);
console.log(jsObject.name);
// 输出: 张三3.3.2、JSON 字符串与 Java 对象的转换
3.3.2.1 引入 Jackson 依赖
如果使用 Maven 项目在 pom.xml 中添加 Jackson 的依赖
dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-databind/artifactIdversion2.12.3/version
/dependency3.2.2.2 JSON 字符串转为 Java 对象
使用 ObjectMapper 类的 readValue() 方法将 JSON 字符串转换为 Java 对象。
import com.fasterxml.jackson.databind.ObjectMapper;public class JsonExample {public static void main(String[] args) throws Exception {String jsonString {\name\:\张三\,\age\:25,\city\:\北京\};// 创建 ObjectMapper 实例ObjectMapper objectMapper new ObjectMapper();// 将 JSON 字符串转换为 Java 对象Person person objectMapper.readValue(jsonString, Person.class);System.out.println(person.getName()); // 输出: 张三}
}class Person {private String name;private int age;private String city;// Getters and Setterspublic String getName() { return name; }public void setName(String name) { this.name name; }public int getAge() { return age; }public void setAge(int age) { this.age age; }public String getCity() { return city; }public void setCity(String city) { this.city city; }
}3.2.2.3 Java 对象转为 JSON 字符串
使用 ObjectMapper 类的 writeValueAsString() 方法将 Java 对象转换为 JSON 字符串。
import com.fasterxml.jackson.databind.ObjectMapper;public class JsonExample {public static void main(String[] args) throws Exception {// 创建一个 Java 对象Person person new Person();person.setName(张三);person.setAge(25);person.setCity(北京);// 创建 ObjectMapper 实例ObjectMapper objectMapper new ObjectMapper();// 将 Java 对象转换为 JSON 字符串String jsonString objectMapper.writeValueAsString(person);System.out.println(jsonString); // 输出: {name:张三,age:25,city:北京}}
}四会话的相关知识
会话创建和持续时间
当用户第一次访问服务器例如第一次登录或访问某个页面时服务器会为用户创建一个新的会话并生成一个唯一的会话 ID。服务器会将这个会话 ID 发送给客户端。在这个会话期间用户的所有请求都会携带这个会话 ID服务器通过这个 ID 识别请求来自同一用户继续使用相同的会话对象。 会话过期或手动销毁
会话有一个过期时间通常设置在服务器的配置中例如 30 分钟或其他时间如果用户在过期时间内没有任何活动即没有请求发给服务器会话将自动失效。用户也可以通过主动“退出登录”来销毁会话此时服务器会手动调用 session.invalidate() 方法立即销毁会话并清除所有会话中的数据。 再次登录会创建新会话
如果用户退出登录或会话过期用户再进行登录时服务器通常会创建一个新的会话。新的会话会重新生成会话 ID不再使用之前的 ID因此之前的会话数据不会继续保留。
五源代码
gittee 地址