Узел js с соединением экспресс-возврата закрыт до получения ответа на рукопожатие - PullRequest
1 голос
/ 07 июня 2019

У меня есть сокет, работающий в nodejs, и использующий этот сокет на html-странице, он работает нормально, и иногда я получаю сообщение об ошибке на консоли разработчика, как ошибка: соединение закрыто до получения ответа на запрос . В этот раз мое обновление не получило отражения на экране пользователя. Фактически всякий раз, когда изменения обновлялись на экране администратора, я записывал логин в laravel, чтобы сохранить эти значения в redis, и я использовал трансляцию событий laravel, а в узле js socket.io считывал изменение значения redis и помещал значения в пользовательские экраны. У меня есть код в Laravel, как, как, Контроллер Laravel,

public function updatecommoditygroup(Request $request)
    {
        $request_data = array();
        parse_str($request, $request_data);
        app('redis')->set("ssahaitrdcommoditydata", json_encode($request_data['commodity']));
        event(new SSAHAITRDCommodityUpdates($request_data['commodity']));
    }

В этом вышеприведенном контроллере при получении вызова API просто сохраните значения в этом ключе redis и передайте событие. В моем классе событий,

public $updatedata;

    public function __construct($updatedata)
    {
        $this->updatedata = $updatedata;
    }
    public function broadcastOn()
    {
        return ['ssahaitrdupdatecommodity'];
    }

Наконец-то я написал свой файл socket.io, как показано ниже,

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var Redis = require('ioredis');
var redis = new Redis({ port: 6379 } );
redis.subscribe('ssahaitrdupdatecommodity', function(err, count) {
});
io.on('connection', function(socket) {
    console.log('A client connected');
});

redis.on('pmessage', function(subscribed, channel, data) {
    data = JSON.parse(data);
    io.emit(channel + ':' + data.event, data.data);
});
redis.on('message', function(channel, message) {
    message = JSON.parse(message);
    io.emit(channel + ':' + message.event, message.data);
});
http.listen(3001, function(){
    console.log('Listening on Port 3001');
});

Когда я обновляю данные от администратора, я передаю их контроллеру laravel, и контроллер сохраняет полученные данные в базу данных redis и передает их в широковещательную рассылку событий. При широковещательной передаче событий значения передаются на сервер сокетов, а сервер сокетов отправляет данные всякий раз, когда ключ redis переходит на страницу клиента. На странице клиента я написал код, как показано ниже,

<script src="../assets/js/socket.io.js"></script>
var socket = io('http://ip:3001/');
socket.on("novnathupdatecommodity:App\\Events\\NOVNATHCommodityUpdates", function(data){
//received data processing in client
});

В большинстве случаев все работает нормально, а иногда возникает проблема, такая как

**VM35846 socket.io.js:7 WebSocket connection to 'ws://host:3001/socket.io/?EIO=3&transport=websocket&sid=p8EsriJGGCemaon3ASuh' failed: Connection closed before receiving a handshake response**

По этой проблеме пользовательская страница не получает обновления с новыми данными. Не могли бы вы, пожалуйста, кто-нибудь помочь мне решить эту проблему и дать лучшее решение для этой проблемы.

1 Ответ

0 голосов
/ 07 июня 2019

Я думаю, это потому, что тайм-аут соединения с сокетом.

new io({
  path:,
  serveClient:,
  orgins:,
  pingTimeout:,
  pingInterval: 
});

Выше приведена конфигурация сокета. Если вы не настраиваете сокет, он иногда ведет себя странно. Я не знаю основной причины, но я тоже столкнулся с похожими проблемами, которые решает реализация конфигурации сокетов.

Сервер Socket.io

Аналогичная конфигурация должна быть выполнена на стороне клиента. На стороне клиента есть опция тайм-аута

Клиент Socket.io

Например.

Скажите, что это ваш код переднего конца Вы подключаетесь к серверу сокетов с помощью следующей команды:

io('http://ip:3001', { path: '/demo/socket' });

На стороне вашего сервера при создании соединения:

const io = require("socket.io");
    const socket = new io({
      path: "/demo/socket",
      serveClient: false /*whether to serve the client files (true/false)*/,
      orgins: "*" /*Supports cross orgine i.e) it helps to work in different browser*/,
      pingTimeout: 6000 /*how many ms the connection needs to be opened before we receive a ping from client i.e) If the client/ front end doesnt send a ping to the server for x amount of ms the connection will be closed in the server end for that specific client*/,
      pingInterval: 6000 /* how many ms before sending a new ping packet */
    });
socket.listen(http);

Примечание: Чтобы избежать сложностей, сначала запустите ваш http-сервер, а затем запустите сокеты. Доступны и другие варианты, но перечисленные выше являются наиболее распространенными.

Я просто описываю то, что вижу в документе socket.io, доступном в github. socket_config . Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...