支持websocket协议
This commit is contained in:
parent
af7c4ebc2f
commit
ded224588e
@ -2,22 +2,20 @@
|
||||
"pages": [
|
||||
"pages/index/index"
|
||||
],
|
||||
"useExtendedLib": {
|
||||
"weui":true
|
||||
},
|
||||
"usingComponents": {
|
||||
"chat-box":"components/chatbox/index"
|
||||
"chat-box": "components/chatbox/index"
|
||||
},
|
||||
"window": {
|
||||
"backgroundTextStyle": "light",
|
||||
"navigationBarBackgroundColor": "#ffffff",
|
||||
"navigationBarTitleText": "New Bing Bot 🤖",
|
||||
"navigationBarTextStyle": "black"
|
||||
"navigationBarTextStyle": "black"
|
||||
},
|
||||
"sitemapLocation": "sitemap.json",
|
||||
"networkTimeout": {
|
||||
"request": 1800000
|
||||
},
|
||||
"resizable": true,
|
||||
"lazyCodeLoading": "requiredComponents"
|
||||
"request": 900000,
|
||||
"connectSocket": 900000
|
||||
},
|
||||
"resizable": true,
|
||||
"lazyCodeLoading": "requiredComponents"
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
const SERVER_HOST = "https://example.com";
|
||||
const SERVER_WSS_HOST = "wss://example.com";
|
||||
|
||||
function doRequest(url, method = "GET", data = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -20,5 +21,6 @@ function doRequest(url, method = "GET", data = {}) {
|
||||
}
|
||||
export {
|
||||
doRequest,
|
||||
SERVER_HOST
|
||||
SERVER_HOST,
|
||||
SERVER_WSS_HOST
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import {
|
||||
doRequest
|
||||
doRequest,
|
||||
SERVER_WSS_HOST
|
||||
} from "../../config";
|
||||
|
||||
const systemInfo = wx.getSystemInfoSync()
|
||||
@ -49,9 +50,14 @@ Page({
|
||||
data: {
|
||||
InputBottom: initHeight,
|
||||
content: "",
|
||||
lastContent: "",
|
||||
systemInfo: systemInfo,
|
||||
textareaFocus: false,
|
||||
searching: false,
|
||||
socket: {
|
||||
socket: null,
|
||||
isOpen: false,
|
||||
},
|
||||
},
|
||||
InputFocus(e) {
|
||||
if (inputPop()) {
|
||||
@ -62,12 +68,12 @@ Page({
|
||||
},
|
||||
InputBlur(e) {
|
||||
this.setData({
|
||||
InputBottom: initHeight,
|
||||
textareaFocus: false,
|
||||
InputBottom: initHeight,
|
||||
textareaFocus: false,
|
||||
});
|
||||
},
|
||||
processContent(content) {
|
||||
return content.replace(/\\n/g, "\n");
|
||||
return content.replace(/\\n/g, "\n").replace(/\[\^\d+\^\]/g, "");
|
||||
},
|
||||
resetConversation: function (callback) {
|
||||
app.getSid(sid => {
|
||||
@ -89,6 +95,77 @@ Page({
|
||||
}
|
||||
},
|
||||
onLoad() {},
|
||||
processData: function (data, suggests, content) {
|
||||
var robContent = data["data"]["status"];
|
||||
if (robContent == "Success") {
|
||||
robContent = data["data"]["text"];
|
||||
suggests.push(...data["data"]["suggests"]);
|
||||
if (robContent.indexOf("New topic") != -1) {
|
||||
robContent += "\n\n发送“重新对话!”开始新的对话";
|
||||
suggests.push("重新对话!");
|
||||
suggests.push(content);
|
||||
}
|
||||
} else {
|
||||
if (robContent == "Throttled") {
|
||||
robContent = "这真是愉快,但你已达到每日限制。是否明天再聊?";
|
||||
suggests.push("重新对话!");
|
||||
suggests.push(content);
|
||||
} else {
|
||||
var msg = data["data"]["message"];
|
||||
if (msg.indexOf("has expired") != -1) {
|
||||
this.resetConversation();
|
||||
robContent = "本轮对话已过期,请重新开始。";
|
||||
suggests.push(content);
|
||||
} else {
|
||||
robContent = "抱歉😭,发生错误:" + msg + ",请重试";
|
||||
suggests.push(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
return robContent
|
||||
},
|
||||
sendWSRequest: function (content) {
|
||||
var that = this
|
||||
app.getSid(sid => {
|
||||
that.sendSocketMessage({
|
||||
"q": content,
|
||||
"sid": sid,
|
||||
"t": new Date().getTime()
|
||||
})
|
||||
})
|
||||
},
|
||||
sendHttpRequest: function (content) {
|
||||
var that = this
|
||||
const cht = app.globalData.cht;
|
||||
app.getSid(sid => {
|
||||
doRequest("/chat", "POST", {
|
||||
q: content,
|
||||
sid: sid,
|
||||
}).then(res => {
|
||||
try {
|
||||
var robContent = ""
|
||||
var suggests = []
|
||||
var num_in_conversation = -1
|
||||
if (res.statusCode != 200) {
|
||||
robContent =
|
||||
"抱歉😭,网络异常,请稍后重试 [" + res.statusCode + "]";
|
||||
suggests.push(content);
|
||||
} else {
|
||||
robContent = that.processData(res.data, suggests, content)
|
||||
num_in_conversation = res.data["data"]["num_in_conversation"];
|
||||
}
|
||||
that.pushStorageMessage(cht, robContent, "rob", suggests, false, true, num_in_conversation)
|
||||
} catch (error) {
|
||||
wx.showToast({
|
||||
title: "fatal error",
|
||||
});
|
||||
that.pushStorageMessage(cht, "发生致命错误😱", "rob", [], false, true)
|
||||
}
|
||||
}).catch(e => {
|
||||
that.pushStorageMessage(cht, e.errMsg, "rob", [], false, true)
|
||||
})
|
||||
})
|
||||
},
|
||||
submitContent: function (content) {
|
||||
if (this.data.searching) {
|
||||
wx.showToast({
|
||||
@ -106,6 +183,7 @@ Page({
|
||||
that.pushStorageMessage(cht, content, "man", [], false)
|
||||
that.setData({
|
||||
content: "",
|
||||
lastContent: content,
|
||||
});
|
||||
if (content == "重新对话!") {
|
||||
that.resetConversation(() => {
|
||||
@ -115,61 +193,10 @@ Page({
|
||||
} else {
|
||||
that.pushStorageMessage(cht, "搜索中🔍...", "rob", [], true)
|
||||
}
|
||||
app.getSid(sid => {
|
||||
doRequest("/chat", "POST", {
|
||||
q: content,
|
||||
sid: sid,
|
||||
}).then(res => {
|
||||
try {
|
||||
var robContent = ""
|
||||
var suggests = []
|
||||
var num_in_conversation = -1
|
||||
if (res.statusCode != 200) {
|
||||
robContent =
|
||||
"抱歉😭,网络异常,请稍后重试 [" + res.statusCode + "]";
|
||||
suggests.push(content);
|
||||
} else {
|
||||
robContent = res.data["data"]["status"];
|
||||
if (robContent == "Success") {
|
||||
robContent = res.data["data"]["text"];
|
||||
suggests = res.data["data"]["suggests"];
|
||||
if (robContent.indexOf("New topic") != -1) {
|
||||
robContent += "\n\n发送“重新对话!”开始新的对话";
|
||||
suggests.push("重新对话!");
|
||||
suggests.push(content);
|
||||
}
|
||||
num_in_conversation = res.data["data"]["num_in_conversation"];
|
||||
} else {
|
||||
if (robContent == "Throttled") {
|
||||
robContent = "这真是愉快,但你已达到每日限制。是否明天再聊?";
|
||||
suggests.push("重新对话!");
|
||||
suggests.push(content);
|
||||
} else {
|
||||
var msg = res.data["data"]["message"];
|
||||
if (msg.indexOf("has expired") != -1) {
|
||||
that.resetConversation();
|
||||
robContent = "本轮对话已过期,请重新开始。";
|
||||
suggests.push(content);
|
||||
} else {
|
||||
robContent = "抱歉😭,发生错误:" + msg + ",请重试";
|
||||
suggests.push(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
that.pushStorageMessage(cht, robContent, "rob", suggests, false, true, num_in_conversation)
|
||||
} catch (error) {
|
||||
wx.showToast({
|
||||
title: "fatal error",
|
||||
});
|
||||
that.pushStorageMessage(cht, "发生致命错误😱", "rob", [], false, true)
|
||||
}
|
||||
}).catch(e => {
|
||||
that.pushStorageMessage(cht, e.errMsg, "rob", [], false, true)
|
||||
})
|
||||
})
|
||||
// that.sendHttpRequest(content)
|
||||
that.sendWSRequest(content)
|
||||
},
|
||||
pushStorageMessage: function (cht, content, role, suggests, blink, pop, num_in_conversation = -1) {
|
||||
pushStorageMessage: function (cht, content, role, suggests, blink, pop, num_in_conversation = -1, final = true) {
|
||||
if (pop) {
|
||||
cht.data.chatList.pop();
|
||||
}
|
||||
@ -185,7 +212,7 @@ Page({
|
||||
cht.setData({
|
||||
chatList: cht.data.chatList,
|
||||
});
|
||||
if (role == "rob" && !blink) {
|
||||
if (role == "rob" && !blink && final) {
|
||||
this.setData({
|
||||
searching: false
|
||||
})
|
||||
@ -221,5 +248,97 @@ Page({
|
||||
this.setData({
|
||||
textareaFocus: true
|
||||
})
|
||||
},
|
||||
openSocket(callback) {
|
||||
if (this.data.socket.isOpen) {
|
||||
return
|
||||
}
|
||||
var that = this
|
||||
const socket = wx.connectSocket({
|
||||
url: SERVER_WSS_HOST + "/chat",
|
||||
fail: function () {
|
||||
wx.showToast({
|
||||
title: '打开websocket失败',
|
||||
})
|
||||
}
|
||||
})
|
||||
socket.onOpen(() => {
|
||||
that.setData({
|
||||
socket: {
|
||||
socket: socket,
|
||||
isOpen: true
|
||||
}
|
||||
})
|
||||
setTimeout(() => {
|
||||
if (callback) {
|
||||
callback()
|
||||
}
|
||||
}, 50)
|
||||
})
|
||||
socket.onClose((code, reason) => {
|
||||
console.log('Socket onClose', code, reason)
|
||||
that.setData({
|
||||
socket: {
|
||||
socket: null,
|
||||
isOpen: false
|
||||
}
|
||||
})
|
||||
})
|
||||
socket.onError(msg => {
|
||||
console.log('Socket onError', msg)
|
||||
that.setData({
|
||||
socket: {
|
||||
socket: null,
|
||||
isOpen: false
|
||||
}
|
||||
})
|
||||
})
|
||||
socket.onMessage(data => {
|
||||
const cht = app.globalData.cht;
|
||||
var data = JSON.parse(data.data)
|
||||
var suggests = []
|
||||
var robContent = ''
|
||||
var num_in_conversation = -1
|
||||
if (!data['final']) {
|
||||
robContent = data['data']
|
||||
} else {
|
||||
robContent = that.processData(data['data'], suggests, that.data.lastContent)
|
||||
num_in_conversation = data['data']['data']['num_in_conversation']
|
||||
}
|
||||
that.pushStorageMessage(cht, robContent, "rob", suggests, false, true, num_in_conversation, data['final'])
|
||||
})
|
||||
},
|
||||
sendSocketMessage: function (data) {
|
||||
if (!this.data.socket.isOpen) {
|
||||
this.openSocket(() => {
|
||||
this.data.socket.socket.send({
|
||||
data: JSON.stringify(data),
|
||||
fail: err => {
|
||||
console.log(err)
|
||||
wx.showToast({
|
||||
title: '消息发送失败',
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.data.socket.socket.send({
|
||||
data: JSON.stringify(data),
|
||||
fail: err => {
|
||||
console.log(err)
|
||||
wx.showToast({
|
||||
title: '消息发送失败',
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
onUnload: function () {
|
||||
if (this.data.socket.isOpen) {
|
||||
this.data.socket.socket.close({
|
||||
code: 1000,
|
||||
reason: "Page Unload"
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -1,5 +1,6 @@
|
||||
# coding=utf-8
|
||||
|
||||
import json as raw_json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
@ -12,6 +13,7 @@ from sanic.response import json
|
||||
from EdgeGPT import Chatbot, ConversationStyle
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
APPID = os.environ.get('WXAPPID')
|
||||
APPSECRET = os.environ.get('WXAPPSECRET')
|
||||
@ -23,6 +25,13 @@ BAK_COOKIE1 = os.environ.get('COOKIE_FILE2', '')
|
||||
|
||||
LOCK = threading.Lock()
|
||||
BOT_LOCK = threading.Lock()
|
||||
bots = {}
|
||||
|
||||
app = Sanic('new-bing')
|
||||
app.config.REQUEST_TIMEOUT = 900
|
||||
app.config.RESPONSE_TIMEOUT = 900
|
||||
app.config.WEBSOCKET_PING_INTERVAL = 15
|
||||
app.config.WEBSOCKET_PING_TIMEOUT = 15
|
||||
|
||||
|
||||
def reset_cookie():
|
||||
@ -40,10 +49,30 @@ def reset_cookie():
|
||||
LOCK.release()
|
||||
|
||||
|
||||
app = Sanic('new-bing')
|
||||
app.config.REQUEST_TIMEOUT = 900
|
||||
app.config.RESPONSE_TIMEOUT = 900
|
||||
bots = {}
|
||||
@app.websocket('/chat')
|
||||
async def ws_chat(request, ws):
|
||||
while True:
|
||||
data = raw_json.loads(await ws.recv())
|
||||
logger.warn('Receive data: %s', data)
|
||||
sid = data['sid']
|
||||
q = data['q']
|
||||
async for response in get_bot(sid).ask_stream(q, conversation_style=ConversationStyle.creative):
|
||||
final, res = response
|
||||
if final:
|
||||
processed_data = await process_data(res, q, sid, auto_reset=1)
|
||||
if processed_data['data']['status'] == 'Throttled':
|
||||
reset_cookie()
|
||||
await get_bot(sid).reset()
|
||||
processed_data['data']['suggests'].append(q)
|
||||
await ws.send(raw_json.dumps({
|
||||
'final': final,
|
||||
'data': processed_data
|
||||
}))
|
||||
else:
|
||||
await ws.send(raw_json.dumps({
|
||||
'final': final,
|
||||
'data': res
|
||||
}))
|
||||
|
||||
|
||||
def get_bot(sid):
|
||||
@ -58,24 +87,16 @@ def get_bot(sid):
|
||||
|
||||
|
||||
async def do_chat(request):
|
||||
logger.warn('Request payload: %s', request.json)
|
||||
return await get_bot(request.json.get('sid')).ask(
|
||||
request.json.get('q'), conversation_style=ConversationStyle.creative
|
||||
)
|
||||
|
||||
|
||||
@app.post('/chat')
|
||||
async def chat(request):
|
||||
res = await do_chat(request)
|
||||
auto_reset = request.json.get('auto_reset', '')
|
||||
sid = request.json.get('sid')
|
||||
status = res['item']['result']['value']
|
||||
if status == 'Throttled':
|
||||
reset_cookie()
|
||||
await get_bot(sid).reset()
|
||||
res = await do_chat(request)
|
||||
status = res['item']['result']['value']
|
||||
async def process_data(res, q, sid, auto_reset=None):
|
||||
text = ''
|
||||
suggests = []
|
||||
status = res['item']['result']['value']
|
||||
if status == 'Success':
|
||||
item = res['item']['messages']
|
||||
if len(item) >= 2:
|
||||
@ -89,18 +110,16 @@ async def chat(request):
|
||||
text = re.sub(r'\[\^\d+\^\]', '', text)
|
||||
suggests = [x['text'] for x in item[1]['suggestedResponses']] if 'suggestedResponses' in item[1] else []
|
||||
else:
|
||||
text = '抱歉,未搜索到结果,请重试。'
|
||||
text = '抱歉,未搜索到结果。'
|
||||
logger.error('响应异常:%s', res)
|
||||
suggests = [request.json.get('q')]
|
||||
# 结束本轮对话
|
||||
suggests = [q]
|
||||
if res['type'] == 2:
|
||||
await get_bot(sid).reset()
|
||||
text = '抱歉,未搜索到结果,已结束本轮对话。'
|
||||
text += '\n\n已结束本轮对话。'
|
||||
msg = res['item']['result']['message'] if 'message' in res['item']['result'] else ''
|
||||
# 自动reset
|
||||
if auto_reset and ('New topic' in text or 'has expired' in msg):
|
||||
await get_bot(sid).reset()
|
||||
return json({
|
||||
return {
|
||||
'data': {
|
||||
'status': status,
|
||||
'text': text,
|
||||
@ -109,8 +128,22 @@ async def chat(request):
|
||||
'num_in_conversation': res['item']['throttling']['numUserMessagesInConversation']
|
||||
if 'throttling' in res['item'] else -1,
|
||||
},
|
||||
'cookie': os.environ.get('COOKIE_FILE')
|
||||
})
|
||||
'cookie': os.environ.get('COOKIE_FILE'),
|
||||
}
|
||||
|
||||
|
||||
@app.post('/chat')
|
||||
async def chat(request):
|
||||
res = await do_chat(request)
|
||||
auto_reset = request.json.get('auto_reset', '')
|
||||
sid = request.json.get('sid')
|
||||
data = await process_data(res, request.json.get('q'), sid, auto_reset)
|
||||
if data['data']['status'] == 'Throttled':
|
||||
reset_cookie()
|
||||
await get_bot(sid).reset()
|
||||
res = await do_chat(request)
|
||||
data = await process_data(res, request.json.get('q'), sid, auto_reset)
|
||||
return json(data)
|
||||
|
||||
|
||||
@app.route('/reset')
|
||||
|
||||
Loading…
Reference in New Issue
Block a user