трансляция в комнату работает на каждом втором соединении в socket.io с Android - PullRequest
0 голосов
/ 28 декабря 2018

Я создал сервер сокетов io, используя nodejs и подключенный к серверу Android.

Я использую io.гнездо: гнездо.io-client: библиотека 1.0.0 для android.

Проблема была в том, когда я пытаюсь отправить сообщение, когда открытое приложение работает.Но когда я переподключаю розетку я это не работает.Просто при втором переподключении всё работает.Каждое второе соединение.Ранее я пытался добавить пользователей в переменную клиента, а затем отправить в socketid.Но сейчас я использую комнаты.

Я думаю, что сервер сокетов io хранит старую комнату, и для второго соединения она работает правильно

Как я могу обновить комнаты перед трансляцией или транслировать последние обновленные комнаты?

server.js

module.exports = (httpsServer) => {
    const io = require('socket.io')(httpsServer, {
        log: false,
        cookie: false,
        multiplex: false
    });
    io.set({
        transports: ['websocket', 'polling']
    });
    io.on('connection', (socket) => {

        ocket.on('join', (id) => {
            console.log(id + " joined");
            socket.join(id);
        });
        socket.on('disconnect', (id) => {
            console.log(id + " leaved");
            socket.leave(id);
        });

        socket.on('messageToUser', (endUserId, msg) => {
            console.log("admin broadcast to: " + endUserId);
            socket.broadcast.to(endUserId).emit('inbox', {
                senderId: '1',
                endUser: endUserId,
                message: msg
            });
            socket.emit('inbox', {
                senderId: '1',
                endUser: endUserId,
                message: msg
            });
        });
    });
};

App.java

public class App extends Application {

    private Socket mSocket;
    {
        try {
            IO.Options opts = new IO.Options();
            opts.secure = true;
            opts.transports = new String[]{WebSocket.NAME};
            opts.reconnection = true;
            opts.forceNew = true;
            opts.multiplex = false;
            mSocket = IO.socket("...",opts);
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }

    public Socket getSocket() {
        return mSocket;
    }
}

ChatActivity.java

    App app = (App) getApplication();
        mSocket = app.getSocket();
        mSocket.on(Socket.EVENT_CONNECT,onConnect);
        mSocket.on(Socket.EVENT_DISCONNECT,onDisconnect);
        mSocket.on(Socket.EVENT_CONNECT_ERROR, onConnectError);
        mSocket.on("inbox", inbox);
        mSocket.connect();
sendButton.setOnClickListener(v -> {
            if (!mSocket.connected()) return;
            if(!messageEditText.getText().toString().trim().isEmpty()){
                mSocket.emit("messageToUser", endUserId, messageEditText.getText().toString()); 
                messageEditText.setText("");
            }
        });

private Emitter.Listener onConnect = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if(!isConnected) {
                        mSocket.emit("join", userInfoSharedP.getUserId()); 
 isConnected = true;
                    }
                }
            });
        }
    };

...

Ответы [ 2 ]

0 голосов
/ 30 декабря 2018

Я нашел проблему.Я использую PM2 Process Manager.И я запускаю PM2 со встроенным балансировщиком нагрузки.Примерно так:

pm2 start server -i 2

И когда я останавливаю pm2 и запускаю собственный сервер узлов, он работает правильно.Мне кажется проблема в балансировке нагрузки с 2 ядрами.И когда я подключаю сокет, каждое второе соединение emit работает.Это происходит из-за разделения процессов на два.

Сначала установите redis

# on mac
brew install redis
sudo brew services start redis

Затем установите адаптер redis socket.io в проекте

npm i socket.io-redis --save

Наконец,

const sockets = require('socket.io')
const redis = require('socket.io-redis')

const bindListeners = (io) => {
  io.on('connection', (socket) => {
    console.log(`${socket.id} connected`)
  })
}

module.exports = (server) => {
  const io = sockets(server, {
    transports: [ 'websocket', 'polling' ]
  })
  // Add the redis adapter
  io.adapter(redis({ host: 'localhost', port: 6379 }))   
  bindListeners(io)
}
0 голосов
/ 29 декабря 2018

вам нужен фоновый или приоритетный сервис для ChatActivity или хотя бы asynctask, также вы можете использовать глобальную публичную переменную для экземпляра сокета, это необходимо для правильной работы

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