修复 WebSocket 会话问题,使用自己实现的简易会话

This commit is contained in:
RockYang 2023-03-22 07:24:31 +08:00
parent 005d219a8c
commit 97acfe57e7
7 changed files with 57 additions and 52 deletions

View File

@ -46,9 +46,9 @@ func (s *Server) ChatHandle(c *gin.Context) {
// 将消息发送给 ChatGPT 并获取结果,通过 WebSocket 推送到客户端 // 将消息发送给 ChatGPT 并获取结果,通过 WebSocket 推送到客户端
func (s *Server) sendMessage(userId string, text string, ws Client) error { func (s *Server) sendMessage(userId string, text string, ws Client) error {
var r = types.ApiRequest{ var r = types.ApiRequest{
Model: "gpt-3.5-turbo", Model: s.Config.Chat.Model,
Temperature: 0.9, Temperature: s.Config.Chat.Temperature,
MaxTokens: 1024, MaxTokens: s.Config.Chat.MaxTokens,
Stream: true, Stream: true,
} }
var history []types.Message var history []types.Message

View File

@ -117,7 +117,7 @@ func corsMiddleware() gin.HandlerFunc {
c.Writer.Header().Set("Access-Control-Allow-Origin", origin) c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE") c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
//允许跨域设置可以返回其他子段,可以自定义字段 //允许跨域设置可以返回其他子段,可以自定义字段
c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, Content-Type, ChatGPT-Token, Session") c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, Content-Type, ChatGPT-Token")
// 允许浏览器(客户端)可以解析的头部 (重要) // 允许浏览器(客户端)可以解析的头部 (重要)
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers") c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers")
//设置缓存时间 //设置缓存时间
@ -148,19 +148,17 @@ func AuthorizeMiddleware(s *Server) gin.HandlerFunc {
return return
} }
tokenName := c.GetHeader("Sec-WebSocket-Protocol") tokenName := c.Query("token")
logger.Info(s.WsSession) if tokenName == "" {
logger.Info(tokenName)
if addr, ok := s.WsSession[tokenName]; ok && addr == c.ClientIP() {
c.Next()
return
}
tokenName = c.GetHeader(types.TokenName) tokenName = c.GetHeader(types.TokenName)
}
// TODO: 会话过期设置
if addr, ok := s.WsSession[tokenName]; ok && addr == c.ClientIP() {
session := sessions.Default(c) session := sessions.Default(c)
user := session.Get(tokenName) user := session.Get(tokenName)
if user != nil { if user != nil {
c.Set(types.SessionKey, user) c.Set(types.SessionKey, user)
}
c.Next() c.Next()
} else { } else {
c.Abort() c.Abort()
@ -193,11 +191,15 @@ func (s *Server) LoginHandle(c *gin.Context) {
sessionId := utils.RandString(42) sessionId := utils.RandString(42)
session := sessions.Default(c) session := sessions.Default(c)
session.Set(sessionId, token) session.Set(sessionId, token)
err = session.Save()
if err != nil {
logger.Error("Error for save session: ", err)
}
// 记录客户端 IP 地址 // 记录客户端 IP 地址
s.WsSession[sessionId] = c.ClientIP() s.WsSession[sessionId] = c.ClientIP()
c.JSON(http.StatusOK, types.BizVo{Code: types.Success, Data: sessionId}) c.JSON(http.StatusOK, types.BizVo{Code: types.Success, Data: sessionId})
} }
func Hello(c *gin.Context) { func Hello(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"code": 0, "message": fmt.Sprintf("HELLO, XWEBSSH !!!")}) c.JSON(http.StatusOK, gin.H{"code": 0, "message": fmt.Sprintf("HELLO, ChatGPT !!!")})
} }

View File

@ -50,9 +50,9 @@ func NewDefaultConfig() *Config {
Domain: "", Domain: "",
Path: "/", Path: "/",
MaxAge: 86400, MaxAge: 86400,
Secure: false, Secure: true,
HttpOnly: false, HttpOnly: false,
SameSite: http.SameSiteLaxMode, SameSite: http.SameSiteNoneMode,
}, },
Chat: Chat{ Chat: Chat{
ApiURL: "https://api.openai.com/v1/chat/completions", ApiURL: "https://api.openai.com/v1/chat/completions",

View File

@ -1,2 +1,2 @@
VUE_APP_API_HOST=172.22.11.200:5678 VUE_APP_API_HOST=127.0.0.1:5678
VUE_APP_API_SECURE=false VUE_APP_API_SECURE=false

View File

@ -1,2 +1,2 @@
VUE_APP_WS_HOST=ws://127.0.0.1:5678 VUE_APP_API_HOST=172.22.11.200:5678
VUE_APP_API_SECURE=false VUE_APP_API_SECURE=false

View File

@ -3,7 +3,7 @@ import {getSessionId} from "@/utils/storage";
axios.defaults.timeout = 5000 axios.defaults.timeout = 5000
axios.defaults.baseURL = process.env.VUE_APP_API_SECURE === true ? 'https://' + process.env.VUE_APP_API_HOST : 'http://' + process.env.VUE_APP_API_HOST axios.defaults.baseURL = process.env.VUE_APP_API_SECURE === true ? 'https://' + process.env.VUE_APP_API_HOST : 'http://' + process.env.VUE_APP_API_HOST
axios.defaults.withCredentials = true axios.defaults.withCredentials = true;
axios.defaults.headers.post['Content-Type'] = 'application/json' axios.defaults.headers.post['Content-Type'] = 'application/json'
// HTTP拦截器 // HTTP拦截器

View File

@ -111,12 +111,7 @@ export default defineComponent({
this.chatBoxHeight = window.innerHeight - this.toolBoxHeight; this.chatBoxHeight = window.innerHeight - this.toolBoxHeight;
}) })
// this.checkSession();
httpPost("/api/session/get").then(() => {
this.connect();
}).catch(() => {
this.showLoginDialog = true;
})
for (let i = 0; i < 10; i++) { for (let i = 0; i < 10; i++) {
this.chatData.push({ this.chatData.push({
@ -139,14 +134,38 @@ export default defineComponent({
}, },
methods: { methods: {
connect: function () { //
if (this.online) { checkSession: function () {
return httpPost("/api/session/get").then(() => {
this.connect();
}).catch((res) => {
if (res.code === 400) {
this.showLoginDialog = true;
} else {
this.connectingMessageBox = ElMessageBox.confirm(
'^_^ 会话发生异常,您已经从服务器断开连接!',
'注意:',
{
confirmButtonText: '重连会话',
cancelButtonText: '不聊了',
type: 'warning',
} }
).then(() => {
this.connect();
}).catch(() => {
ElMessage({
type: 'info',
message: '您关闭了会话',
})
})
}
})
},
connect: function () {
// WebSocket // WebSocket
const token = getSessionId(); const token = getSessionId();
const socket = new WebSocket('ws://' + process.env.VUE_APP_API_HOST + '/api/chat', [token]); const socket = new WebSocket('ws://' + process.env.VUE_APP_API_HOST + '/api/chat?token=' + token);
socket.addEventListener('open', () => { socket.addEventListener('open', () => {
ElMessage.success('创建会话成功!'); ElMessage.success('创建会话成功!');
@ -193,24 +212,8 @@ export default defineComponent({
}); });
socket.addEventListener('close', () => { socket.addEventListener('close', () => {
ElMessageBox.confirm( //
'^_^ 会话发生异常,您已经从服务器断开连接!', this.checkSession();
'注意:',
{
confirmButtonText: '重连会话',
cancelButtonText: '不聊了',
type: 'warning',
}
)
.then(() => {
this.connect();
})
.catch(() => {
ElMessage({
type: 'info',
message: '您关闭了会话',
})
})
}); });
this.socket = socket; this.socket = socket;