Electron:socket.io 可以接收但不能发射 [英] Electron: socket.io can receive but not emit
问题描述
我正在创建一个使用 Socket.io 与服务器应用程序通信的 Electron 应用程序,但我遇到了一个奇怪的问题:虽然我的 Electron 应用程序成功加入并从我的服务器接收消息,但它完全没有发出任何东西.
客户端:
const io = require('socket.io-client');//...var socket = io("http://localhost:8081");socket.on('欢迎', () => {console.log('欢迎收到');//显示socket.emit('测试')});socket.on('错误', (e) => {控制台.log(e);//不显示});socket.on('ok', () => {console.log("OK 收到");//不显示});socket.on('连接', () => {console.log("已连接");//显示socket.emit('test');});
服务器端:
io.on('connection', (client) => {io.emit('欢迎');client.on("测试", () => {console.log("收到测试");//不显示io.emit("ok");})});io.listen(8081);
请注意,还有一个 Web 客户端连接到服务器,并且完全按预期工作.
我做错了什么?
Electron 有可以有节点集成的主进程和有
应用控制台:
注意
为避免这种情况,您必须将 WS 服务器添加到 CSP.对于本地主机,在 index.html
标头中使用它:
<meta http-equiv="Content-Security-Policy" content="default-src 'self' ws://localhost:*/socket.io/; script-src 'self' ws://localhost:*/socket.io/"><meta http-equiv="X-Content-Security-Policy" content="default-src 'self' ws://localhost:*/socket.io/; script-src 'self' ws://localhost:*/socket.io/">
它是所有端口的本地主机服务器,当然它只是用于开发,你必须在生产中进入正常的 WS 服务器.
您可以从 Github 克隆并检查我的工作示例:https://github.com/clytras/电子插座
编辑最后但并非最不重要的;检查并允许 nodejs 和/或防火墙中的端口的传入/传出访问.
电子版:7.1.2节点版本:12.8.1
I'm creating an Electron application that uses Socket.io to communicate to a server application, but I'm experiencing a weird issue: whereas my Electron app successfully joins and receives messages from my server, it completely fails to emit anything.
Client-side:
const io = require('socket.io-client');
// ...
var socket = io("http://localhost:8081");
socket.on('welcome', () => {
console.log('welcome received'); // displayed
socket.emit('test')
});
socket.on('error', (e) => {
console.log(e); // not displayed
});
socket.on('ok', () => {
console.log("OK received"); // not displayed
});
socket.on('connect', () => {
console.log("connected"); // displayed
socket.emit('test');
});
Server-side:
io.on('connection', (client) => {
io.emit('welcome');
client.on("test", () => {
console.log("received test"); // not displayed
io.emit("ok");
})
});
io.listen(8081);
Note that there is also a Web client that connects to the server, and works absolutely as expected.
What am I doing wrong?
Electron has the main process that can have node integration and renderer process that has nodeIntegration
turned off by default for security reasons.
If you try to use your client code in the main process (main.js) it will work and receive/emit normal. But if you try to use the client code on the rendered process, then it won't work. You need to add the client code inside the preload.js
and then preload it using the webPreferences.preload
option of the BrowserWindow
like this:
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
...
}
Then you can have the client code inside preload.js
:
const io = require('socket.io-client');
const socket = io(`http://localhost:${process.env.SOCKET_PORT}`);
socket.on('welcome', () => {
console.log('on welcome : welcome received renderer'); // displayed
socket.emit('test')
});
socket.on('error', (e) => {
console.log(e); // displayed ?
});
socket.on('ok', () => {
console.log("OK received renderer"); // displayed
});
socket.on('connect', () => {
console.log("connected renderer"); // displayed
socket.emit('test');
});
begin the socket, start the electron app and see it working:
Socket server:
App console:
Beware of the Content Security Policy (CSP):
To avoid this, you have to add your WS server to your CSP. For localhost use this inside index.html
header:
<meta http-equiv="Content-Security-Policy" content="default-src 'self' ws://localhost:*/socket.io/; script-src 'self' ws://localhost:*/socket.io/">
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self' ws://localhost:*/socket.io/; script-src 'self' ws://localhost:*/socket.io/">
It's a localhost server for all ports and of course it's for development only, you have to enter normal WS server in production.
You can clone and check my working example from Github: https://github.com/clytras/electron-sockets
EDIT Last but not least; check and allow incomming/outgoing access for nodejs and/or port in firewal.
Electron version: 7.1.2
Node version: 12.8.1
这篇关于Electron:socket.io 可以接收但不能发射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!