У меня есть веб-сайт, использующий React и Socket.io/socket.io-client. Когда я читаю сообщение, я хочу, чтобы это сообщение отображалось всем пользователям моего сайта.
Я проверил свой код локально, и все работает нормально. Тем не менее, когда я загрузил это на эластичный beanstalk на AWS, мой поток Twitter перестает работать через час или 2.
На внешнем интерфейсе я вижу такие ошибки:
Не удалось загрузить ресурс: сервер ответил со статусом 400 (неверный запрос)
и
Соединение WebSocket с 'ws: //my.ip.address/socket.io/? EIO = 3 & transport = websocket & sid = 6LwyF5lDoVH1mArYAJGJ' не удалось: ошибка во время рукопожатия WebSocket: неожиданный код ответа: 400
В серверной части я не вижу никаких ошибок, но вижу много подключений и отключений Io.
Когда я перезагружаю сервер. Работает около часа, а потом я перестаю получать новые сообщения.
В настоящее время у нас работают 3 пользователя, поэтому я не совсем понимаю, почему у нас так много подключений / отключений
У меня такое чувство, что я плохо управляю своими соединениями, но не знаю, как это исправить.
это мой пакет. Json
{
"name": "xxxx",
"version": "0.1.0",
"private": true,
"main": "app.js",
"dependencies": {
"@emotion/core": "^10.0.0-beta.11",
"ajv": "^6.6.2",
"axios": "^0.18.0",
"eslint": "5.11.1",
"express": "^4.16.4",
"lodash.sortby": "^4.7.0",
"moment": "^2.22.2",
"npm-run-all": "^4.1.5",
"react": "^16.6.1",
"react-date-range": "^0.9.4",
"react-dom": "^16.6.1",
"react-google-login": "^3.2.1",
"react-helmet": "^5.2.0",
"react-redux": "^5.1.0",
"react-router": "^4.3.1",
"react-router-dom": "^4.3.1",
"react-scripts-ts": "^2.16.0",
"react-spinners": "^0.4.7",
"react-transition-group": "^1.2.1",
"redux": "^4.0.1",
"redux-thunk": "^2.3.0",
"socket.io": "^2.2.0",
"socket.io-client": "^2.2.0",
"twitter": "^1.7.1"
},
"proxy": "http://localhost:3001",
"scripts": {
"start": "react-scripts-ts start",
"build": "react-scripts-ts build",
"test": "react-scripts-ts test --env=jsdom",
"eject": "react-scripts-ts eject"
},
"devDependencies": {
"@types/jest": "^23.3.9",
"@types/node": "^10.12.3",
"@types/react": "^16.4.18",
"@types/react-dom": "^16.0.9",
"@types/react-redux": "^6.0.9",
"@types/redux": "^3.6.31",
"typescript": "^3.2.2"
}
}
это мой app.js
const express = require('express');
const http = require('http');
const socketio = require('socket.io');
const path = require('path');
const bodyParser = require('body-parser');
const port = process.env.PORT || 3001;
const hostname = 'localhost'
const app = express();
require('dotenv').config();
app.all('/*', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
const server = http.createServer(app);
const io = socketio(server).listen(server);
app.use(bodyParser.json());
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
require('./server/routes/twitter.js')(app, io);
server.listen(port, hostname,() => {
console.log('server is up');
console.log('server listening on: ', hostname, ':', port);
});
const Twitter = require('twitter');
module.exports = (app, io) => {
var IO = io;
var twitter = new Twitter({
consumer_key: "xxx",
consumer_secret: "xxx",
access_token_key: "xxx",
access_token_secret: "xxx",
});
var socketConnection;
var twitterStream;
twitter.stream('statuses/filter', { follow: 'xxxx' }, (stream) => {
stream.on('data', (tweet) => {
console.log("new message found")
console.log(tweet.text)
sendMessage(tweet);
});
stream.on('error', (error) => {
console.log("twitter stream error")
console.log(error);
});
twitterStream = stream;
});
//Establishes socket connection.
io.on("connection", socket => {
console.log("connection io : " + socket.id)
socketConnection = socket;
socket.on("connection", () => console.log("Client connected " + socket.id));
socket.on("disconnect", () => console.log("Client disconnected : " + socket.id));
/**
* Emits data from stream.
* @param {String} msg
*/
const sendMessage = (msg) => {
console.log("in sendMessage")
if (msg.text.includes('RT')) {
return;
}
console.log("trying to send tweet")
IO.emit("tweets", msg);
console.log("msg broadcasted")
}
};
import * as React from 'react';
import request from 'src/libs/request';
import * as socketIOClient from "socket.io-client";
import { Tweet } from './../../store/interfaces/index';
import * as moment from 'moment';
interface TweetItem {
user: string,
message: string,
created: string
}
class SideBar extends React.Component {
state: Tweet = {
tweets : [],
isLoading: true,
wsTweets:[],
error: '' }
componentDidMount() {
this.openSocket();
}
public openSocket() {
const socket = socketIOClient('http://my.ip.address/');
socket.on('connect', () => {
console.log("Twitter Socket Connected");
socket.on("tweets", (data:any) => {
console.log(data);
var tweet = {created: parseInt(data.timestamp_ms,10),
message: data.text,
user: data.user.name
}
console.log(this.state.tweets)
console.log(tweet)
var newTweets = [tweet].concat(this.state.tweets);
console.log(newTweets)
// this.setState({ wsTweets: tweet })
this.setState({ tweets: newTweets })
});
});
socket.on('disconnect', () => {
socket.off("tweets")
socket.removeAllListeners();
console.log("Socket Disconnected");
this.openSocket();
console.log("reopening...")
});
socket.on('error', (exception:any) => {
console.log('TWITTER SOCKET ERROR');
console.log(exception)
})
}
render() {
}
}
export default SideBar;