如何在 express 的获取请求中执行 websocket 连接事件?
Posted
技术标签:
【中文标题】如何在 express 的获取请求中执行 websocket 连接事件?【英文标题】:how to do websocket connection event inside of express`s get request? 【发布时间】:2020-02-26 08:30:28 【问题描述】:我试图在 express 的 router.get 请求中获取 websocket
这里是代码
app.js
const createServer = require("http");
const mongoose = require('mongoose');
const config = require('./config');
const WebSocket = require('ws');
const app = express();
app.use(express.json());
app.use(express.urlencoded( extended: true ));
const server = createServer(app);
app.use("/RegisterApi", require("./Routes/RegisterApi/RegisterApi"));
const wss = new WebSocket.Server( server );
app.wss = wss;
app.locals.clients = [];
server.listen(config.PORT, function ()
console.log(`im listening at $config.PORT`);
mongoose.connect(config.MONGODB_URI,
useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true,
useFindAndModify: false
)
RegisterApi.js
const router = express.Router();
const nodemailer = require("nodemailer");
const Users = require("../../Models/YakutGamesUserModel");
const WebSocket = require('ws');
//const jwt = require("jsonwebtoken");
router.get('/login'/*,verifyToken*/, async (req, res) =>
console.log(req.query.name);
const currentUser = await Users.findOne( name: req.query.name );
const userunchecked = false;
if (!currentUser)
res.send("invalid user ");
userunchecked = true;
else if (!currentUser.confirmed)
res.send("confirm your email " + currentUser.name); userunchecked = true;
else if (currentUser.password !== req.query.password) res.send("password is wrong"); userunchecked = true;
const wss = req.app.wss;
const clients = req.app.locals.clients;
await wss.once("connection", (ws, request) =>
console.log("Total connected clients:", wss.clients.size);
const ip = request.connection.remoteAddress;
console.log(ip);
if (userunchecked) ws.delete; console.log('wtf'); return;
const userObject = id: currentUser._id, object: ws ;
clients.push(userObject);
ws.send("ID= " + currentUser._id);
);
);
那些是服务器端 作为客户我使用统一
unity code C#
async void Login()
newUser.name = namefield.text;
newUser.password = passfield.text;
string url = String.Format("http://localhost:7989/RegisterApi/login?name=0&password=1", newUser.name, newUser.password);
StartCoroutine(LoginUser(url, () => Debug.Log("login req done"); ));
websocket = new WebSocket("ws://localhost:7989/RegisterApi/login");
websocket.OnOpen += () =>
Debug.Log("Connection open!");
;
websocket.OnError += (e) =>
Debug.Log("Error! " + e);
;
websocket.OnClose += (e) =>
Debug.Log("Connection closed!");
;
websocket.OnMessage += (bytes) =>
var message = System.Text.Encoding.UTF8.GetString(bytes);
Debug.Log("OnMessage! " + message);
;
await websocket.Connect();
问题是服务器没有得到 console.log("Total connected clients:", wss.clients.size);第一次当我从统一启动登录功能时。但是如果我第二次触发登录服务器得到它,但这次 wss.clients.size 将是 2 。
我做错了什么?
【问题讨论】:
【参考方案1】:我认为您正在尝试登录,使用 http 请求可以登录一次。
这段代码对我有用。
IEnumerator LoginUser(string url, Action onSuccess)
UnityWebRequest req = UnityWebRequest.Get(url);
yield return req.SendWebRequest();
while (!req.isDone)
yield return null;
string result = req.downloadHandler.text;
string[] resultArray = result.Split(' ');
if (resultArray[0] == "yourCode")
myTempID = resultArray[1];
Debug.Log(myTempID);
Wss(myTempID);
LoginLog.GetComponent<TextMeshProUGUI>().text = "login done";
mainMenuButtonHandlersGO.GetComponent<MainMenuButtonHandlers>().OpenFirstCanvasButtons();
messageHandlerGO.GetComponent<WssMessageHandler>().MessageHandlerFunction();
else LoginLog.GetComponent<TextMeshProUGUI>().text = result;
onSuccess();
async void Wss(string code)
websocket = new WebSocket(String.Format("ws://1:7989/RegisterApi/login?parentID=0", code, mainAddress));
websocket.OnOpen += () =>
Debug.Log("Connection open!");
;
websocket.OnError += (e) =>
Debug.Log("Error! " + e);
;
websocket.OnClose += (e) =>
Debug.Log("Connection closed!");
;
// Keep sending messages at every 0.3s
//InvokeRepeating("SendWebSocketMessage", 0.0f, 5.0f);
// waiting for messages
await websocket.Connect();
【讨论】:
以上是关于如何在 express 的获取请求中执行 websocket 连接事件?的主要内容,如果未能解决你的问题,请参考以下文章
详解express搭建http服务,通过路由和中间件获取静态文件和动态数据的实现原理
无法从 Flutter Web 上的 localhost API(node js express)获取 http 请求的响应 [重复]