下午好。我是在 node.js 中編程套接字的新手,我需要在我的應用程式的控制器中實作 socket.io。我擁有的架構如下:
啟動服務器的檔案是 index.js
const express = require('express');
const app = express();
const port = 3000;
const socketRouter = require('./routes/socket')
app.use(express.json());
//Route
app.use('/socket', socketRouter);
app.listen(port, () => {
console.log(`Server connection on http://127.0.0.1:${port}`); // Server Connnected
});
我定義路由的檔案是 socket.js
const { Router } = require('express');
const { showData } = require('../controllers/socket');
const router = Router();
router.post('/send-notification', showData);
module.exports = router;
我的控制器是:
const { response } = require('express');
const showData = (req, res = response) => {
const notify = { data: req.body };
//socket.emit('notification', notify); // Updates Live Notification
res.send(notify);
}
module.exports={
showData
}
我需要在這個控制器中實作 socket.io 才能從它發出,但我不能讓它作業。你能告訴我怎么做嗎?非常感謝
澄清:如果我在主檔案中實作 socket.io 它可以作業,但我想要一些順序和單獨的東西。這是它的作業原理:
const express = require('express');
const app = express();
const port = 3000;
app.use(express.json());
app.post('/send-notification', (req, res) => {
const notify = { data: req.body };
socket.emit('notification', notify); // Updates Live Notification
res.send(notify);
});
const server = app.listen(port, () => {
console.log(`Server connection on http://127.0.0.1:${port}`); // Server Connnected
});
const socket = require('socket.io')(server);
socket.on('connection', socket => {
console.log('Socket: client connected');
});
uj5u.com熱心網友回復:
如果您想按功能分隔套接字訊息和 REST 端點,或者您選擇組織它,您可以在其他檔案中使用相同的socket和app(如果您還需要公開 API)。以下是如何做到這一點的示例:
創建一個新檔案,假設controller1.js:
function initialize(socket, app) {
socket.on('some-socket-message', socket => {
// Whatever you want to do
});
app.get('/some-endpoint', (req, res) => {
// whatever you want to do
});
}
module.exports = {initialize}
然后將以下內容添加到您的 controller.js
const controller1 = require('path/to/controller1');
...
// At some point after socket and app have been defined
controller1.initalize(socket, app);
這將是根據需要分離控制器的基礎,同時仍然在所有控制器中使用相同的套接字連接和 API 埠。您也可以將initialize方法重構為不同的方法,但這取決于您自己的判斷以及您希望如何命名函式等。它也不需要被呼叫initalize,這只是我的偏好名稱。
uj5u.com熱心網友回復:
將您的 socket.io 代碼移動到它自己的模塊中,您可以在其中匯出一個共享 socket.io 服務器實體的方法:
// local socketio.js module
const socketio = require('socket.io');
let io;
modules.exports = {
init: function(server) {
io = socketio(server);
return io;
},
getIO: function() {
if (!io) {
throw new Error("Can't get io instance before calling .init()");
}
return io;
}
}
然后,在您的主應用程式檔案中初始化 socketio.js 模塊:
const express = require('express');
const app = express();
const port = 3000;
app.use(express.json());
const server = app.listen(port, () => {
console.log(`Server connection on http://127.0.0.1:${port}`); // Server Connnected
});
// initialize your local socket.io module
const sio = require('./socketio.js');
sio.init(server);
// now load socket.io dependent routes
// only after .init() has been called on socket.io module
const socketRouter = require('./routes/socket')
app.use('/socket', socketRouter);
然后,在任何你想訪問 socket.io 服務器實體的地方,你都可以
require("./socketio.js")使用該.getIO()方法來獲取 socket.io 實體:
// use correct path to socketio.js depending upon where this module
// is located in the file system
const io = require("../../socketio.js").getIO();
// some Express route in a controller
const showData = (req, res) => {
const notify = { data: req.body };
// send notification to all connected clients
io.emit('notification', notify);
res.send(notify);
};
module.exports= {
showData
};
注意:服務器上典型的 socket.io 使用約定是io用作服務器實體和socket單獨的客戶端連接套接字實體。請不要嘗試同時使用socket兩者。這清楚地表明io.emit(...)正在嘗試發送到所有連接的客戶端并socket.emit()嘗試發送到單個連接的客戶端。
另請注意,如果您的路由是由瀏覽器本身發送表單帖子的表單帖子觸發的,那么該特定客戶端將不會io.emit(...)從該表單帖子路由接收完成的結果,因為該瀏覽器將處于加載新網頁的程序中頁面基于表單發布的回應,并將破壞其當前的 socket.io 連接。如果表單發布完全通過 Javascript 使用 Ajax 呼叫完成,則該網頁將保持活動狀態并接收io.emit(...).
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/412077.html
標籤:
上一篇:如何制作React搜索組件
