Socket.io on docker-compose stack (Node + Angular)
Socket.io on docker-compose stack (Node + Angular)
我正在尝试将 Socket.io
集成到具有前端 (Angular
+ Nginx
) 和后端 (Node.JS
Express
)。此实例的目标是在实例之间实时广播消息。
但是当我使用 Nginx
部署它时,这不起作用,而且我没有收到任何错误消息。我收到的唯一日志来自前端,它是“localhost”上的代码 200
。
src-frontend-1 | 172.27.0.1 - - [26/Apr/2022:08:18:05 +0000] "POST /socket.io/?EIO=4&transport=polling&t=O1aylEl&sid=KfZQUO36iFaqoKlWAAAA HTTP/1.1" 200 2 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36" "-"
请注意,当我 运行 在我的开发计算机上使用 ng serve
和 npm run dev
时代码有效
这是我的后端:
const PORT = process.env.PORT || 8080;
const app = express();
const httpServer = new createServer(app);
const io = new Server(httpServer, {
cors: {
origin: {
origin: "http://localhost:8080",
},
allowedHeaders: ["socket.io"],
credentials: true,
},
});
io.on("connection", (socket) => {
console.log("new socket connected");
socket.on("process", (data) => {
console.log(`New data received : ${data}`);
newDataSocket = data.isOperation; //Status of instances
console.log("result data socket :", newDataSocket);
socket.broadcast.emit("processChanged", data);
}); // listen to the event
socket.on("error", function (err) {
console.log("Socket.IO Error");
console.log(err); // this is changed from your code in last comment
});
});
httpServer.listen(6379, () => {
console.log(`[app with socket.io] : Listening on PORT 6379`);
});
前端 core.module.ts 配置
import { SocketIoModule, SocketIoConfig } from 'ngx-socket-io';
const config: SocketIoConfig = { url: /socket.io/, options: {} };
前端服务套接字
export class SocketIoService {
constructor(private socket: Socket) {}
sendMessage(msg: object) {
console.log('msg sended from front===>', msg);
this.socket.emit('process', msg);
}
getMessage() {
return this.socket.fromEvent<any>('processChanged')
}
}
Dockerfile 后端
FROM node:14-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
# Bundle app source
COPY . .
EXPOSE 8080 6379
CMD [ "node", "app.js" ]
Nginx 配置
location /socket.io/ {
proxy_pass http://api:6379;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
和 docker-compose 文件
version: '3.4'
services:
api:
build:
context: './backend'
ports:
- 8080:8080
frontend:
build:
context: './frontend'
ports:
- 80:80
depends_on:
- api
links:
- api
更新
所以,有些人误解了我的意思,有些人在文档中遗漏了。
- 如果前面没有
http
,ngx-socket-io
库不支持 url 字符串。所以我需要添加域。我在我的 REST 调用中使用了 /api
而没有 http
import { SocketIoModule, SocketIoConfig } from 'ngx-socket-io';
const config: SocketIoConfig = { url: 'http://localhost/socket.io', options: {} };
- 如果选项中没有
path
,ngx-socket-io
默认添加/socket.io
。
import { SocketIoModule, SocketIoConfig } from 'ngx-socket-io';
const config: SocketIoConfig = { url: 'http://localhost', options: {} };
- 我在后台选项里也加了
path
,不知道有没有用
const io = new Server(httpServer, {
path: "/socket.io",
cors: {
origin: [CORS_POLICY],
methods: ["GET", "POST"]
}
});
它的作品。
我的请求是 200,但在 Chrome 的网络控制台中,我错过了“错误的命名空间”错误,这有助于我找到原因。
我正在尝试将 Socket.io
集成到具有前端 (Angular
+ Nginx
) 和后端 (Node.JS
Express
)。此实例的目标是在实例之间实时广播消息。
但是当我使用 Nginx
部署它时,这不起作用,而且我没有收到任何错误消息。我收到的唯一日志来自前端,它是“localhost”上的代码 200
。
src-frontend-1 | 172.27.0.1 - - [26/Apr/2022:08:18:05 +0000] "POST /socket.io/?EIO=4&transport=polling&t=O1aylEl&sid=KfZQUO36iFaqoKlWAAAA HTTP/1.1" 200 2 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36" "-"
请注意,当我 运行 在我的开发计算机上使用 ng serve
和 npm run dev
时代码有效
这是我的后端:
const PORT = process.env.PORT || 8080;
const app = express();
const httpServer = new createServer(app);
const io = new Server(httpServer, {
cors: {
origin: {
origin: "http://localhost:8080",
},
allowedHeaders: ["socket.io"],
credentials: true,
},
});
io.on("connection", (socket) => {
console.log("new socket connected");
socket.on("process", (data) => {
console.log(`New data received : ${data}`);
newDataSocket = data.isOperation; //Status of instances
console.log("result data socket :", newDataSocket);
socket.broadcast.emit("processChanged", data);
}); // listen to the event
socket.on("error", function (err) {
console.log("Socket.IO Error");
console.log(err); // this is changed from your code in last comment
});
});
httpServer.listen(6379, () => {
console.log(`[app with socket.io] : Listening on PORT 6379`);
});
前端 core.module.ts 配置
import { SocketIoModule, SocketIoConfig } from 'ngx-socket-io';
const config: SocketIoConfig = { url: /socket.io/, options: {} };
前端服务套接字
export class SocketIoService {
constructor(private socket: Socket) {}
sendMessage(msg: object) {
console.log('msg sended from front===>', msg);
this.socket.emit('process', msg);
}
getMessage() {
return this.socket.fromEvent<any>('processChanged')
}
}
Dockerfile 后端
FROM node:14-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
# Bundle app source
COPY . .
EXPOSE 8080 6379
CMD [ "node", "app.js" ]
Nginx 配置
location /socket.io/ {
proxy_pass http://api:6379;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
和 docker-compose 文件
version: '3.4'
services:
api:
build:
context: './backend'
ports:
- 8080:8080
frontend:
build:
context: './frontend'
ports:
- 80:80
depends_on:
- api
links:
- api
更新
所以,有些人误解了我的意思,有些人在文档中遗漏了。
- 如果前面没有
http
,ngx-socket-io
库不支持 url 字符串。所以我需要添加域。我在我的 REST 调用中使用了/api
而没有http
import { SocketIoModule, SocketIoConfig } from 'ngx-socket-io';
const config: SocketIoConfig = { url: 'http://localhost/socket.io', options: {} };
- 如果选项中没有
path
,ngx-socket-io
默认添加/socket.io
。
import { SocketIoModule, SocketIoConfig } from 'ngx-socket-io';
const config: SocketIoConfig = { url: 'http://localhost', options: {} };
- 我在后台选项里也加了
path
,不知道有没有用
const io = new Server(httpServer, {
path: "/socket.io",
cors: {
origin: [CORS_POLICY],
methods: ["GET", "POST"]
}
});
它的作品。 我的请求是 200,但在 Chrome 的网络控制台中,我错过了“错误的命名空间”错误,这有助于我找到原因。