socket.io - не может заставить его работать, имея 404 на каком-то опросе
Я пытаюсь настроить сервер с помощью socket.io с плохими результатами.
Я в основном следую этому руководству, хотя оно несколько устарело: http://www.williammora.com/2013/03/nodejs-tutorial-building-chatroom-with.html
Проблема возникает с socket.io, я не уверен, что это на стороне клиента или сервера. Похоже, что он пытается постоянно опрашивать сервер, но возвращает 404. Звучит так, что socket.io не работает, но все выглядит хорошо для меня. Это также может быть связано с путями и наличием "публичного" каталога, но я не совсем знаю.
127.0.0.1 - - [Thu, 17 Jul 2014 00:51:36 GMT] "GET /socket.io/?EIO=2&transport=polling&t=1405558296120-0 HTTP/1.1" 404 73 "http://localhost:8080/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.76.4 (KHTML, like Gecko) Version/7.0.4 Safari/537.76.4"
127.0.0.1 - - [Thu, 17 Jul 2014 00:51:37 GMT] "GET /socket.io/?EIO=2&transport=polling&t=1405558297181-1 HTTP/1.1" 404 73 "http://localhost:8080/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.76.4 (KHTML, like Gecko) Version/7.0.4 Safari/537.76.4"
127.0.0.1 - - [Thu, 17 Jul 2014 00:51:39 GMT] "GET /socket.io/?EIO=2&transport=polling&t=1405558299207-2 HTTP/1.1" 404 73 "http://localhost:8080/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.76.4 (KHTML, like Gecko) Version/7.0.4 Safari/537.76.4"
сервер
var exec = require( "child_process" ).exec;
var path = require( "path" );
var morgan = require( "morgan" );
var bodyParser = require( "body-parser" );
var _ = require( "underscore" );
var express = require( "express" );
var app = express();
var http = require( "http" ).createServer( app );
var io = require( "socket.io" )( http );
app.set( "ipaddr", "127.0.0.1" );
app.set( "port", 8080 );
//support JSON, urlencoded, and multipart requests
app.use( bodyParser() );
//log the requests using morgan
app.use( morgan() );
//specify the Jade views folder
app.set( "views", __dirname + "/../views" );
//set the view engine to Jade
app.set( "view engine", "jade" );
//specify static content
app.use( express[ "static" ]( "public", __dirname + "/../public" ) ); //using map-access of static so jslint won't bitch
io.on( "connection", function( socket )
{
console.log( "A user connected." );
});
клиент
script( src="js/socket.io.js" )
var socket = io.connect( "http://localhost:8080" );
Я получил клиентский js-файл из: node_modules / socket.io / node_modules / socket.io-client / socket.io.js
Этот путь не совпадает ни с тем, что говорится в учебном пособии, которое я использую, ни с тем, что использует socket.io, так что, возможно, это проблема, но, похоже, это правильный файл.
Любая помощь здесь?
РЕДАКТИРОВАТЬ Для получения дополнительной информации, вот моя иерархия папок:
Webserver/
my_modules/
server.js
node_modules/
body-parser/
express/
jade/
morgan/
socket.io/
underscore/
public/
css/
js/
server.js
views/
index.jade
index.js
package.json
Server.js в папке my_modules - это то место, где я запускаю socket.io на стороне сервера. Server.js в папке js - это клиентский код для подключения с веб-сайта.
6 ответов
Похоже, Socket.IO не может перехватывать запросы, начиная с /socket.io/
, Это потому, что в вашем случае слушатель app
- Экспресс-обработчик. Вы должны сделать http
быть слушателем, так что Socket.IO будет иметь доступ к обработке запросов.
Попробуй заменить
app.set( "ipaddr", "127.0.0.1" );
app.set( "port", 8080 );
с
http.listen(8080, "127.0.0.1");
Подробности смотрите в документации: http://socket.io/docs/
В моем случае я создал свое приложение с помощью генератора приложений Express. Чтобы решить эту проблему, вместо того, чтобы редактировать файл app.js в корневой папке проекта, я отредактировал файл bin/www в строке после определения сервера:
/**
* Create HTTP server.
*/
var server = http.createServer(app);
var io = require('socket.io')(server); // Add this here
Обновить
Я нашел лучший способ здесь Express Generator и Socket.io
Просто для проверки, что это ваш сервер или просто проблема клиента, вы можете использовать этот web: websocket-echo, если этот клиент подключается прямо к вашему серверу (первый клиент формы полезен, если ваш сервер подключен к сети, если он находится на вашем хосте, см. websocket.org...
С помощью текстового редактора скопируйте следующий код и сохраните его как websocket.html где-нибудь на жестком диске.
Код: websocket-тест
Единственное, что отличалось от моего, которое я мог наблюдать, это исходный код клиента: <script src="/socket.io/socket.io.js"></script>
на вашей стороне клиента.
На вашем сервере вы должны попробовать этот способ:
var express = require('express'),
app = express(),
http = require('http'),
server = http.createServer(app),
io = require('socket.io').listen(server),
exec = require('child_process').exec,
util = require('util');
//serve our code
app.use(express.static('public'));
app.use(express.json());
app.use(express.urlencoded());
//listening on connections
io.on('connection', function (socket) {
console.log('client connected!');
}
server.listen(8080);
Обратите внимание, что этот способ отлично работает с этими зависимостями: я рекомендую добавить следующий код в файл package.json:
"dependencies": {
"express": "3.x.x",
"socket.io": "*",
"util": "*"
}
ура!
Повторная публикация здесь, так как другой ответ не помог мне, и этот помог. Мне потребовалось время, чтобы найти его, так что, надеюсь, я сэкономлю часть вашего времени.
Пожалуйста , перейдите этого ответатуда и upvote Josan Iracheta ответ «s , если он вам помог.
import io from 'socket.io-client'
const socket = io('http://localhost:3000', {
reconnectionDelay: 1000,
reconnection: true,
reconnectionAttemps: 10,
transports: ['websocket'],
agent: false,
upgrade: false,
rejectUnauthorized: false
});
Пользователи NextJS и ExpressJS:
Возможно, вам будет полезно узнать, как подключиться к пользовательскому URL-адресу.
- На клиенте и сервере должен быть настроен один и тот же путь (
/socket.io
по умолчанию). - Клиент должен запросить правильный URL-адрес инициализатора (
/socket.io?<querystring>
по умолчанию)
Если вам нужно создать собственную конечную точку для вашего сервера WebSocket, например, потому что вы реализуете ее внутри системы API NextJS или иным образом реализуете ее внутри структуры ограниченного пути, вы должны установить путь как на клиенте, так и на сервере. .
В этом примере
- клиент получает конечную точку HTTP на сервере по адресу
/api/socket
, - Сервер инициализирует сервер WebSocket, который еще не активен. Это происходит потому, что конечная точка HTTP загружает сервер WebSocket.
- Клиент обращается к серверу WebSocket по адресу
/api/socket/socket.io
Обратите внимание, что WebSocket принимаетpath
переменная и создает новый веб-сервер в .
Стоит понимать, что сервер WebSocket также создает собственный HTTP-сервер по адресу${path}/socket.io
, к которому подключается клиент и получает информацию JSON о том, как подключиться к фактическому сокету. Этот HTTP-сервер отличается от HTTP-сервера ExpressJS или NextJS.
Сервер
import { Server, Socket } from "socket.io";
// server is provided by expressJS or NextJS in this example
// NextJS: const server = req.socket.server;
// ExpresssJS: const server = http.createServer(app);
// pseudocode for a REST API handler at `/api/socket`
const httpRouteHandler = (request: Request, response: Response) {
// if the WebSocket server is already running, do nothing
if (server.io) {
response.end();
return;
}
// Note that this variable represents the WebSocket server URL
// which may or may not be the same as the REST API endpoint,
// depending on your framework or organizational restrictions
const socketRootUrl = "/api/socket";
const io = new Server(server, { path: socketRootUrl });
// connect events here
// store the WebSocket server somewhere
server.io = io;
res.end();
}
Клиент
import io from "socket.io-client";
// this path must match the server's path setting
const socketRootUrl = "/api/socket";
// tell the server to open a WebSocket server
await fetch(socketRootUrl);
// connect to the WebSocket Server with the custom path
const socket = io({
path: `${socketRootUrl}/socket.io`,
});
Тестирование
Вы можете проверить, подключаетесь ли вы к правильному URL-адресу HTTP-сервера WebSocket.
curl "https://example.com/api/socket/socket.io/?EIO=4&transport=polling"
Если соединение прошло успешно, вы получите ответ в формате JSON:
0{"sid":"Lbo5JLzTotvW3g2LAAAA","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":5000}
Вам не следует привязывать Socket.io к серверу HTTP-соединений. Всегда меняйте app.listen на http.listen
Вот пример из моего файла index.ts:
// Express server
const app: express.Application = express();
// Node.JS HTTP server
const httpServer = createServer(app);
// Socket.IO server
const io = new Server(httpServer,{
cors: {
origin: "*",
},
});
// Start server with socket.io and express attached
httpServer.listen(process.env.PORT || 8081, function () {
console.log("App started at port:", process.env.PORT || 8081)
})
Если у вас возникнут какие-либо проблемы, дайте мне знать, я всегда открыт для новых обсуждений. Спасибо