So i set up a small basic chat system:
Server code:
var io = require('socket.io').listen(8000);
// open the socket connection
io.sockets.on('connection', function (socket) {
// listen for the chat even. and will recieve
// data from the sender.
socket.on('chat', function (data) {
// default value of the name of the sender.
var sender = 'unregistered';
// get the name of the sender
var name = socket.nickname;
console.log('Chat message by ', name);
console.log('error ', err);
sender = name;
// broadcast data recieved from the sender
// to others who are connected, but not
// from the original sender.
socket.broadcast.emit('chat', {
msg : data,
msgr : sender
});
});
// listen for user registrations
// then set the socket nickname to
socket.on('register', function (name) {
// make a nickname paramater for this socket
// and then set its value to the name recieved
// from the register even above. and then run
// the function that follows inside it.
socket.nickname = name;
// this kind of emit will send to all! :D
io.sockets.emit('chat', {
msg : "naay nag apil2! si " + name + '!',
msgr : "mr. server"
});
});
});
Client side:
<html>
<head>
<script src="http://localhost:8000/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
<script>
var name = '';
var socket = io.connect('http://localhost:8000');
// at document read (runs only ones).
$(document).ready(function(){
// on click of the button (jquery thing)
// the things inside this clause happen only when
// the button is clicked.
$("button").click(function(){
// just some simple logging
$("p#log").html('sent message: ' + $("input#msg").val());
// send message on inputbox to server
socket.emit('chat', $("input#msg").val() );
// the server will recieve the message,
// then maybe do some processing, then it will
// broadcast it again. however, it will not
// send it to the original sender. the sender
// will be the browser that sends the msg.
// other browsers listening to the server will
// recieve the emitted message. therefore we will
// need to manually print this msg for the sender.
$("p#data_recieved").append("<br />rn" + name + ': ' + $("input#msg").val());
// then we empty the text on the input box.
$("input#msg").val('');
});
// ask for the name of the user, ask again if no name.
while (name == '') {
name = prompt("What's your name?","");
}
// send the name to the server, and the server's
// register wait will recieve this.
socket.emit('register', name );
});
// listen for chat event and recieve data
socket.on('chat', function (data) {
// print data (jquery thing)
$("p#data_recieved").append("<br />rn" + data.msgr + ': ' + data.msg);
// we log this event for fun :D
$("p#log").html('got message: ' + data.msg);
});
</script>
</head>
<body>
<input type="text" id="msg"></input><button>Click me</button>
<p id="log"></p>
<p id="data_recieved"></p>
</body>
</html>
While it works pretty well, everytime i pass something to the server from the client i get an:
«throw er; // unhandled ‘error’ event.
ReferenceError: err is not defined.
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and
privacy statement. We’ll occasionally send you account related emails.
Already on GitHub?
Sign in
to your account
Closed
mathiask88 opened this issue
Aug 9, 2014
· 21 comments
· Fixed by #160
Comments
Hey,
I implemented a redis adapter in this way
var socketioPub = m_redis.createClient(null, null, { detect_buffers: true }); socketioPub.on('error', function (err) { ... }); var socketioSub = m_redis.createClient(null, null, { detect_buffers: true }); socketioSub.on('error', function (err) { ... }); io.adapter(m_socketio_redis({ pubClient: socketioPub, subClient: socketioSub }));
So if the redis server e.g. is not running I can handle that error, but I get an unhandled error event from https://github.com/Automattic/socket.io-redis/blob/master/index.js#L73
[...] function Redis(nsp){ Adapter.call(this, nsp); var self = this; sub.psubscribe(prefix + '#*', function(err){ if (err) self.emit('error', err); <-------------------------------- }); sub.on('pmessage', this.onmessage.bind(this)); } [...]
because there is no event listener attached and I see no way to attach one from the outside. Any ideas?
Best regards!
The adapter inherits from Emitter
, so simply attach an error
listener on the emitter instance.
@guille, could you please advise on valid syntax for ‘error’ event. I can’t find any working solution.
Attach it on the adapter instance? On the object you pass to io.adapter
Guillermo, thanks for your feedback, unfortunately it doesn’t work with v. 0.1.3. Here is my code:
var redis = require('socket.io-redis');
var redisAdapter = redis({ host: 'abc', port: 12345 });
redisAdapter.on('error', function(err) {});
io.adapter(redisAdapter);
There is no ‘on’ method in redisAdapter object. Here is error:
redisAdapter.on('error', function(err) {});
^
TypeError: Object function Redis(nsp){
Adapter.call(this, nsp);
var self = this;
sub.psubscribe(prefix + '#*', function(err){
if (err) self.emit('error', err);
});
sub.on('pmessage', this.onmessage.bind(this));
} has no method 'on'
Try redisAdapter.prototype.on('error', function(err) {});
that worked for me. But it feels a bit strange to edit the prototype…
It’s not working for me. When I kill Redis server, whole app crashes:
events.js:72
throw er; // Unhandled 'error' event
I’m having the same issue, please reopen.
The emit in the psubscribe callback is throwing an error, which can’t be catched in a good way.
https://github.com/Automattic/socket.io-redis/blob/master/index.js#L73
I did add an error event handler:
var adapter = io.adapter(socketIORedis({ key: 'socket.io-redis-experiment',
pubClient: pub,
subClient: sub}));
adapter.on('error',function(err) {
debug('adapter error: ',err);
});
Adding a error listener on self
, just before sub.psubscribe
solves the unhandled error…
self.on('error',function(err) { console.log("socket.io-redis inside error handler: ",err); });
Maybe the right instance reference isn’t returned from the require?
Putting a listener on adapter.prototype actually works… That’s far from intuitive…
Example:
var adapter = socketIORedis(); adapter.prototype.on('error',function(err) { debug('adapter error: ',err); }); io.adapter(adapter);
I think I understand the problem, require('socket.io-redis')
returns a «class» and every namespace creates it’s own adapter instance from this.
I tried the solution suggested by @peteruithoven but no luck… The error is still thrown causing a crash of the application. Is there some news about this issue?
@emidiocroci, did you also try adding error listeners to the pub and sub clients?
Small example:
io.adapter(initRedisAdapter(config.REDIS_PORT,config.REDIS_HOST)); function initRedisAdapter(port,host) { var pub = redis.createClient(port,host,{detect_buffers: true}); pub.on('error',onRedisError); var sub = redis.createClient(port,host,{detect_buffers: true}); sub.on('error',onRedisError); var redisAdapter = RedisAdapter({pubClient: pub, subClient: sub, key: 'your key'}); redisAdapter.prototype.on('error',onRedisError); function onRedisError(err){ debug("Redis error: ",err); } return redisAdapter; }
You can access to an adapter instance like:
io.of('/').adapter.on('error', funtion(err) {});
Thanks @peteruithoven, worked like a charm!
Where did you find those info about redis adapter initialization?
Source code of socket.io
@nkzawa 3x! You are right. Using radis adapter API also need to add of(namespace)!!!
io.of('/').adapter.on('error', funtion(err) {});
this didn’t work for me,
only adding the handler to the prototype as @peteruithoven suggesed worked for me
Same. Using version 5.2.0
and only catching errors on the pubClient and subClient still caused my app to crash.
Error: connect ECONNREFUSED 127.0.0.1:6379
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1117:14)
Adding:
adapter.prototype.on("error", err => logger.error("PROTOTYPE", { err }));
will prevent the app from crashing:
2018-10-25T10:17:56.307Z error: PROTOTYPE [err: Error: connect ECONNREFUSED 127.0.0.1:6379] [severity: ERROR]
2018-10-25T10:17:56.308Z error: PROTOTYPE [err: Error: connect ECONNREFUSED 127.0.0.1:6379] [severity: ERROR]
2018-10-25T10:17:56.467Z error: PROTOTYPE [err: MaxRetriesPerRequestError: Reached the max retries per request limit (which is 3). Refer to "maxRetriesPerRequest" option for details.] [severity: ERROR]
However, it will not retry forever to establish the Redis connection and will stay zombie.
Same. Using version
5.2.0
and only catching errors on the pubClient and subClient still caused my app to crash.Error: connect ECONNREFUSED 127.0.0.1:6379 at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1117:14)
Adding:
adapter.prototype.on("error", err => logger.error("PROTOTYPE", { err }));
will prevent the app from crashing:
2018-10-25T10:17:56.307Z error: PROTOTYPE [err: Error: connect ECONNREFUSED 127.0.0.1:6379] [severity: ERROR] 2018-10-25T10:17:56.308Z error: PROTOTYPE [err: Error: connect ECONNREFUSED 127.0.0.1:6379] [severity: ERROR] 2018-10-25T10:17:56.467Z error: PROTOTYPE [err: MaxRetriesPerRequestError: Reached the max retries per request limit (which is 3). Refer to "maxRetriesPerRequest" option for details.] [severity: ERROR]
However, it will not retry forever to establish the Redis connection and will stay zombie.
To keep the reconnection protocol, instantiate the redis client separately from the adapter. Implement reconnection protocols on this redis client and let it reconnect. Let adapter.prototype.on catch the error handle even redundantly. That way, you’ll get the best of both worlds.
Подключен модуль https://github.com/TooTallNate/node-socks-proxy-agent . Несмотря на то что написано Build Status Failing, модуль работает исправно на wss
Вот ошибка, которая стопорит скрипт. Мне нужно, чтоб скрипт продолжал работать:
events.js:72
throw er; // Unhandled 'error' event
^
Error: Connection Timed Out
at Socket.onTimeout (/home/admin/web/*/public_html/node_modules/socks-proxy-agent/node_modules/socks/lib/socks-client.js:55:20)
at Socket.g (events.js:180:16)
at Socket.EventEmitter.emit (events.js:92:17)
at Socket._onTimeout (net.js:327:8)
at Timer.unrefTimeout [as ontimeout] (timers.js:412:13)
Вот те самые строки из socks-client.js:55 (finish(new Error 55 строка))
exports.createConnection = function (options, callback) {
var socket = new net.Socket(), finished = false, buff = new SmartBuffer();
// Defaults
options.timeout = options.timeout || 10000;
options.proxy.command = commandFromString(options.proxy.command);
options.proxy.userid = options.proxy.userid || "";
var auth = options.proxy.authentication || {};
auth.username = auth.username || "";
auth.password = auth.password || "";
options.proxy.authentication = auth;
// Connect & negotiation timeout
function onTimeout() {
finish(new Error("Connection Timed Out"), socket, null, callback);
}
socket.setTimeout(options.timeout, onTimeout);
// Socket events
socket.once('close', function () {
finish(new Error("Socket Closed"), socket, null, callback);
});
socket.once('error', function (err) {
});
Тут надо читать медленно:
Т.к соединений в WS очень много (700 подключений через разные socks proxy сервера), безусловно где-то будет ошибка таймаута. Сначала такая же ошибка выпадала при ws.on close. Я пересоздавал (делал реконект). Убрал я её пересозданием самого объекта agent от socks-proxy-agent и она пропала. Выпала снова в тот момент, когда начал поднимать более 700 соединений. Методом тыка пришел к выводу, что один из socks proxy просто в таймаут не ответил. Но в итоге стопорится весь скрипт.
ADD:
При изменении timeout до 100000 (100 секунд я так понимаю)
events.js:72
throw er; // Unhandled 'error' event
^
Error: socket hang up
at SecurePair.error (tls.js:1013:23)
at EncryptedStream.CryptoStream._done (tls.js:705:22)
at CleartextStream.read [as _read] (tls.js:496:24)
at CleartextStream.Readable.read (_stream_readable.js:320:10)
at EncryptedStream.onCryptoStreamFinish (tls.js:301:47)
at EncryptedStream.g (events.js:180:16)
at EncryptedStream.EventEmitter.emit (events.js:92:17)
at finishMaybe (_stream_writable.js:356:12)
at endWritable (_stream_writable.js:363:3)
at EncryptedStream.Writable.end (_stream_writable.js:341:5)
ADD2:
Нашел файл по адресу: /node_modules/casperjs/modules/events.js (причем тут casperjs я так и не понял, хотя папка node_modules). И там как раз 72 строка:
EventEmitter.prototype.emit = function emit() {
var type = arguments[0];
// If there is no 'error' event listener then throw.
if (type === 'error') {
if (!this._events || !this._events.error ||
(isArray(this._events.error) && !this._events.error.length))
{
if (arguments[1] instanceof Error) {
throw arguments[1]; // Unhandled 'error' event
} else {
throw new CasperError("Uncaught, unspecified 'error' event.");
}
}
}
if (!this._events) return false;
var handler = this._events[type];
if (!handler) return false;
if (typeof handler === 'function') {
try {
switch (arguments.length) {
// fast cases
case 1:
handler.call(this);
break;
case 2:
handler.call(this, arguments[1]);
break;
case 3:
handler.call(this, arguments[1], arguments[2]);
break;
// slower
default:
var l = arguments.length;
var args = new Array(l - 1);
for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
handler.apply(this, args);
}
} catch (err) {
this.emit('event.error', err);
}
return true;
ADD
Error(«Connection Timed Out»), socket, null, callback); вот эту строку заменил на просто console.log. Выпадает 8-9 строк таких, а потом выпадает Error: socket hang up. Где эту ошибку заблокировать я не нашел. У меня нет файла в системе tls.js. Пипец. Бесит.
Node.js (с socket.io и экспресс) throw «events.js:71 throw arguments[1]; // Необработанное событие «ошибка»»
Я запускаю экспресс (через прокси-сервер nginx) с socket.io, и через несколько секунд (приложение какое-то время работает нормально) консоль выдает это:
events.js:71
throw arguments[1]; // Unhandled 'error' event
^
Error: socket hang up
at createHangUpError (http.js:1360:15)
at ServerResponse.OutgoingMessage._writeRaw (http.js:507:26)
at ServerResponse.OutgoingMessage._send (http.js:476:15)
at ServerResponse.OutgoingMessage.write (http.js:749:16)
at XHRPolling.doWrite (/home/xyz/chat/node_modules/socket.io/lib/transports/xhr-polling.js:67:17)
at XHRPolling.HTTPPolling.write (/home/xyz/chat/node_modules/socket.io/lib/transports/http-polling.js:132:8)
at XHRPolling.Transport.onDispatch (/home/xyz/chat/node_modules/socket.io/lib/transport.js:222:10)
at Socket.dispatch (/home/xyz/chat/node_modules/socket.io/lib/socket.js:230:38)
at Socket.packet (/home/xyz/chat/node_modules/socket.io/lib/socket.js:214:10)
at Socket.emit (/home/xyz/chat/node_modules/socket.io/lib/socket.js:368:15)
Есть идеи?
1 ответы
ответ дан 02 мар ’13, в 15:03
Не тот ответ, который вы ищете? Просмотрите другие вопросы с метками
node.js
express
socket.io
or задайте свой вопрос.
Я запускаю http-сервер NodeJS + Socket.io для отправки новостных статей клиентам с 7:00 до 17:00. Днём всё работает нормально (клиенты подключаются, отключаются без сбоев сервера), но иногда ночью вылетает (примерно раз в неделю). Сервер ничего не делает (т.е. очищает веб-сайт) в одночасье, поэтому это должна быть io.sockets.on(‘connection’, function (socket) {…} часть кода, которая вызывает сбой.
Кроме того, я недавно добавил сайт в Google Search Console через <meta name = «google-site-verification» content = «…» /> Возможно ли, что бот Google вызывает сбой?
Я не могу получить IP-адрес, с которого был сделан запрос, потому что происходит сбой до того, как что-либо будет записано в файл журнала.
Ошибка:
node:events:491
throw er; // Unhandled 'error' event
^
Error: Parse Error: Invalid method encountered
Emitted 'error' event on Socket instance at:
at emitErrorNT (node:internal/streams/destroy:151:8)
at emitErrorCloseNT (node:internal/streams/destroy:116:3)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
bytesParsed: 299,
code: 'HPE_INVALID_METHOD',
reason: 'Invalid method encountered',
rawPacket: Buffer(316) [Uint8Array] [
80, 79, 83, 84, 32, 47, 71, 112, 111, 110, 70, 111,
114, 109, 47, 100, 105, 97, 103, 95, 70, 111, 114, 109,
63, 105, 109, 97, 103, 101, 115, 47, 32, 72, 84, 84,
80, 47, 49, 46, 49, 13, 10, 72, 111, 115, 116, 58,
32, 49, 50, 55, 46, 48, 46, 48, 46, 49, 58, 56,
48, 13, 10, 67, 111, 110, 110, 101, 99, 116, 105, 111,
110, 58, 32, 107, 101, 101, 112, 45, 97, 108, 105, 118,
101, 13, 10, 65, 99, 99, 101, 112, 116, 45, 69, 110,
99, 111, 100, 105,
... 216 more items
]
}
Node.js v18.12.1
Вот упрощенная версия server.js
var express = require('express')
var app = express()
var server = require('http').createServer(app)
var io = require('socket.io')(server);
/*
bunch of code that runs during the day, but not when server crashes
*/
connections = []
server.listen(80)
console.info('running')
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html')
})
// after the first crash, I added the try{...}catch(err){...} to try to prevent the server from crashing, but it still crashes
try{
io.sockets.on('connection', function (socket) {
// NOTE: the server crashed before any of the below executed, so I assume its the io.sockets.on(...) abo
var date = new Date();
var dashdate = (date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear() + " " + date.getHours() + ':' + ("0" + date.getMinutes()).slice(-2) + ':' + ("0" + date.getSeconds()).slice(-2);
console.info(dashdate) //to log date+time client connected
console.info(socket.handshake.address) //client ip address
console.info(socket.id) //socket id
connections.push(socket) //push socket to array to keep list of connected clients
console.info('connected: %s sockets connected', connections.length) //log the connection
// emit to client that they are connected
io.to(socket.id).emit('new message', { msg: 'Connected - ' + date.getHours() + ':' + ("0" + date.getMinutes()).slice(-2) + ':' + ("0" + date.getSeconds()).slice(-2) , link: '' })
// on disconnect
socket.on('disconnect', function (data) {
connections.splice(connections.indexOf(socket), 1);
console.info('disconnected: %s sockets connected', connections.length);
});
//send message
socket.on('send message', function (data) {
io.sockets.emit('new message', { msg: data });
})
});
}catch(err){console.info(err)}
Я нашел, что кто-то еще написал о той же самой ошибке, но нет информации о решении: https://github.com/Ylianst/MeshCentral/issues/4482
В одном ответе говорится: …что-то или кто-то отправляет мусорные данные в потоке TLS, и в результате соединение TLS закрывается. Это может быть вызвано ботами, сетевыми сканерами и т. д.
В конце концов, мне не нужно блокировать запрос, но как мне обработать ошибку, чтобы она не привела к сбою server.js?
я запускаю приложение Express js с помощью socket.io для чата
webapp и я получаю следующую ошибку случайным образом около 5 раз во время
24ч. Процесс узел, завернутый в навсегда и он перезапускается
сама сразу же.
проблема в том, что перезапуск express выбивает моих пользователей из своих комнат
и никто этого не хочет.
веб-сервер определяется на основе графических интерфейсов. Нет проблем со стабильностью сокета, просто используя websockets и flashsockets транспорты. Я не могу воспроизвести это нарочно.
это ошибка с узлом v0. 10. 11:
events.js:72
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET //alternatively it s a 'write'
at errnoException (net.js:900:11)
at TCP.onread (net.js:555:19)
error: Forever detected script exited with code: 8
error: Forever restarting script for 2 time
EDIT (2013-07-22)
добавлены оба socket.io обработчик ошибок клиента и обработчик неперехваченных исключений. Кажется, что это один ловит ошибку:
process.on('uncaughtException', function (err) {
console.error(err.stack);
console.log("Node NOT Exiting...");
});
так что я подозреваю, что это не a socket.io проблема, но http-запрос на другой сервер, который я делаю, или соединение mysql/redis. Проблема в том, что стек ошибок не помогает мне определить мою проблему с кодом. Вот вывод журнала:
Error: read ECONNRESET
at errnoException (net.js:900:11)
at TCP.onread (net.js:555:19)
как я узнаю, что вызывает это? Как мне получить больше от ошибки?
хорошо, не очень многословно, но вот stacktrace с «longjohn»:
Exception caught: Error ECONNRESET
{ [Error: read ECONNRESET]
code: 'ECONNRESET',
errno: 'ECONNRESET',
syscall: 'read',
__cached_trace__:
[ { receiver: [Object],
fun: [Function: errnoException],
pos: 22930 },
{ receiver: [Object], fun: [Function: onread], pos: 14545 },
{},
{ receiver: [Object],
fun: [Function: fireErrorCallbacks],
pos: 11672 },
{ receiver: [Object], fun: [Function], pos: 12329 },
{ receiver: [Object], fun: [Function: onread], pos: 14536 } ],
__previous__:
{ [Error]
id: 1061835,
location: 'fireErrorCallbacks (net.js:439)',
__location__: 'process.nextTick',
__previous__: null,
__trace_count__: 1,
__cached_trace__: [ [Object], [Object], [Object] ] } }
здесь я служу файл политики флэш-сокета:
net = require("net")
net.createServer( (socket) =>
socket.write("<?xml version="1.0"?>n")
socket.write("<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">n")
socket.write("<cross-domain-policy>n")
socket.write("<allow-access-from domain="*" to-ports="*"/>n")
socket.write("</cross-domain-policy>n")
socket.end()
).listen(843)
может ли это быть причиной?