Хорошо, я искал почти каждый вопрос / ответ, который я могу найти об этом в SO и других местах в Интернете, но безрезультатно. Итак, я решил опубликовать это, чтобы увидеть, есть ли у кого направление, чтобы указать мне.
Настройка
У меня есть приложение React и Node / Express API на отдельных поддоменах. Приложение React находится на сайте www.domain.com, а API - на сайте api.domain.com. Приложение React использует конечные точки, предоставляемые приложением Express (api.domain.com/endpoint и т. Д.).
Кроме того, Express API использует Socket.io для некоторых коммуникаций в реальном времени и предоставляется на том же порту, что и сам API.
Все это обслуживает Apache2.
Соответствующие образцы кода
Мой корневой файл Express (index.js):
const app = require('express', '4.16.4')();
const bodyParser = require('body-parser');
const cors = require('cors');
const http = require('http').createServer(app);
const io = require('socket.io')(http);
require('./sockets/chat')(io);
const db = require('./services/db.service');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cors({
credentials: true,
}));
const projects = require('./routes/projects');
const assets = require('./routes/assets');
app.use('/projects', projects);
app.use('/assets', assets);
// Test API endpoint
app.get('/test', (req, res) => {
res.send('You got me');
});
db.connect();
http.listen(4002, () => {
console.log('API is ready on 4002');
});
/sockets/chat
, который импортируется в вышеуказанный файл:
const Message = require('../models/message.model');
module.exports = (io) => {
io.on('connection', (socket) => {
socket.on('message', async ({ asset, from, body }) => {
const msg = new Message({
asset,
from,
body,
});
const message = await msg.save();
io.emit('message', message);
});
});
};
Компонент React Chat
, который обрабатывает интерфейс с Socket.io:
import React, { Component } from 'react';
import ChatMessage from '../ChatMessage';
import { Auth0Lock } from '../Auth';
import socketIOClient from 'socket.io-client';
import MessageService from '../../services/message.service';
import { apiUrl, loginCallback } from '../../config';
require('./styles.scss');
class Chat extends Component {
constructor(props) {
super(props);
this.state = {
messages: [],
}
}
componentDidMount() {
MessageService.getAssetMessages(this.props.assetId)
.then((messages) => {
this.setState({ messages })
})
.catch((e) => console.log(e));
this.socket = socketIOClient(apiUrl, {transports: ['websocket']});
this.socket.on('message', (message) => {
this.setState({
messages: [
...this.state.messages,
message,
],
});
});
this.socket.on('connect_error', (err) => {
console.log('SocketIO connection error:', err);
});
}
И конфиг Apache2, который находится перед API (на поддомене):
# Added to mitigate CVE-2017-8295 vulnerability
UseCanonicalName On
<VirtualHost *:80>
ServerName api.reviewcycle.io
RewriteCond %{SERVER_NAME} =api.reviewcycle.io
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=301]
ErrorLog ${APACHE_LOG_DIR}/error-reviewcycle-api.log
</VirtualHost>
<VirtualHost *:443>
ServerName api.reviewcycle.io
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/socket.io/ [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) wss://localhost:4002/$1 [P,L]
SSLEngine On
SSLCertificateFile /etc/cloudflare/reviewcycle.io.pem
SSLCertificateKeyFile /etc/cloudflare/reviewcycle.io.key
ProxyPass / http://localhost:4002/
ProxyPassReverse / http://localhost:4002/
</VirtualHost>
Проблема
Когда приложение загружается и модуль пытается установить соединение с Socket.io, происходит сбой следующим образом:
Что касается детализации запроса сети:
Я перепробовал почти все, что только мог придумать, включая кучу изменений в конфигурации Apache. Я чувствую, что где-то в пути, Apache не передает запрос на Express правильно, но я не уверен.
Если кто-нибудь увидит здесь что-нибудь неладное, я был бы очень благодарен за помощь! Также будем рады предоставить любую другую информацию, которая может понадобиться для отслеживания этой информации!
ТИА!