Jak wysłać wiadomość do konkretnego klienta z socket.io

Zaczynam od socket.io + węzeł.js, wiem jak wysłać wiadomość lokalnie i nadawać socket.broadcast.emit() funkcja: - wszyscy podłączeni klienci otrzymują tę samą wiadomość.

Teraz chciałbym wiedzieć, jak wysłać prywatną wiadomość do konkretnego klienta, mam na myśli jedno gniazdo do Prywatnego czatu między 2 osoby (Client-to-Client stream). Dzięki.

Author: Sangram Singh, 2013-07-04

7 answers

Gdy użytkownik łączy się, powinien wysłać wiadomość do serwera z nazwą użytkownika, która musi być unikalna, jak e-mail.

Para username i socket powinna być przechowywana w obiekcie takim jak:

var users = {
    '[email protected]': [socket object],
    '[email protected]': [socket object],
    '[email protected]': [socket object]
}

Na kliencie emituje obiekt do serwera z następującymi danymi:

{
    to:[the other receiver's username as a string],
    from:[the person who sent the message as string],
    message:[the message to be sent as string]
}

Na serwerze, Słuchaj wiadomości. Po odebraniu wiadomości Wyślij dane do odbiornika.

users[data.to].emit('receivedMessage', data)

Na kliencie nasłuchuj emisji z serwera o nazwie 'receivedMessage', odczytując dane, możesz poradzić sobie z tym, od kogo pochodzą i z wysłaną wiadomością.

 104
Author: Adam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-08 10:01:26

Możesz użyć socket.io pokoje. Od strony klienta emituje Zdarzenie ("join" w tym przypadku może to być cokolwiek) z dowolnym unikalnym identyfikatorem (email, id).

Strona Klienta:

var socket = io.connect('http://localhost');
socket.emit('join', {email: [email protected]});

Teraz, Od strony serwera użyj tych informacji, aby stworzyć unikalny pokój dla tego użytkownika

Strona Serwera:

var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {
  socket.on('join', function (data) {
    socket.join(data.email); // We are using room of socket io
  });
});

Więc teraz każdy użytkownik dołączył do pokoju nazwanego po e-mailu użytkownika. Więc jeśli chcesz wysłać konkretnemu użytkownikowi wiadomość, po prostu musisz

Serwer Strona:

io.sockets.in('[email protected]').emit('new_msg', {msg: 'hello'});

Ostatnią rzeczą do zrobienia po stronie klienta jest wysłuchanie zdarzenia "new_msg".

Strona Klienta:

socket.on("new_msg", function(data) {
    alert(data.msg);
}
Mam nadzieję, że rozumiesz.
 292
Author: az7ar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-11 19:20:09

Pewnie: Po prostu,

To jest to, czego potrzebujesz:

io.to(socket.id).emit("event", data);

Za każdym razem, gdy użytkownik dołączył do serwera, zostaną wygenerowane dane gniazda, w tym ID. To jest ID naprawdę pomaga wysłać wiadomość do konkretnych osób.

Najpierw musimy zapisać wszystkie gniazda.ids in array,

var people={};

people[name] =  socket.id;

Tutaj nazwa jest nazwą odbiorcy. Przykład:

people["ccccc"]=2387423cjhgfwerwer23;
/ Align = "left" / socket.id z nazwą odbiorcy, gdy wysyłamy wiadomość:

W tym celu musimy znam nazwisko zarządcy. Musisz emitować nazwę odbiornika do serwera.

Ostatnia rzecz to:

 socket.on('chat message', function(data){
io.to(people[data.receiver]).emit('chat message', data.msg);
});

Mam nadzieję, że to zadziała dobrze dla Ciebie.

Powodzenia!!
 35
Author: Trojan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-06 12:25:55

Możesz odnieść się do socket.io pokoje . Po uściśnięciu dłoni-możesz dołączyć do niego do nazwanego pokoju, np. " user.# {userid}".

Następnie możesz wysłać prywatną wiadomość do dowolnego klienta za pomocą dogodnej nazwy, na przykład:

Io.sockets.in ('user.125'). emit('new_message', {text: "Hello world"})

W operacji powyżej wysyłamy "new_message "do użytkownika"125".

Dzięki.
 9
Author: Vladimir Kurijov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-05 14:18:40

W projekcie naszej firmy stosujemy podejście "rooms" i jego nazwa jest połączeniem identyfikatorów użytkowników wszystkich użytkowników w rozmowie jako unikalnego identyfikatora (nasza implementacja jest bardziej jak Facebook messenger), przykład:

|id / Nazwa / 1 / Scott / 2 / Susan

Nazwa"pokój" będzie "1-2" (identyfikatory są zamawiane Asc.) i po rozłączeniu socket.io automatycznie czyści pokój

W ten sposób wysyłasz wiadomości tylko do tego pokoju i tylko do użytkowników online (podłączonych) (mniej Pakiety wysyłane przez serwer).

 5
Author: Rami,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-20 19:22:04

Jako az7ar odpowiedź jest pięknie powiedziana, ale pozwól mi uprościć to z socket.io pokoje. poproś o serwer z unikalnym identyfikatorem, aby dołączyć do serwera. tutaj używamy e-maila jako unikalnego identyfikatora.

Klient Socket.io

socket.on('connect', function () {
  socket.emit('join', {email: [email protected]});
});
Kiedy użytkownik dołączył do serwera, Utwórz pokój dla tego użytkownika

Serwer Socket.io

io.on('connection', function (socket) {
   socket.on('join', function (data) {    
    socket.join(data.email);
  });
});

Teraz jesteśmy gotowi do przyłączenia. niech emituje coś z serwera to pokój, tak, że użytkownik może słuchać.

Serwer Socket.io

io.to('[email protected]').emit('message', {msg: 'hello world.'});

Zakończmy temat odsłuchując message zdarzenie po stronie klienta

socket.on("message", function(data) {
  alert(data.msg);
});

Odniesienie z Socket.io pokoje

 5
Author: Lalit Mohan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-02 03:50:29

Oto pełne rozwiązanie dla Klienta Android + Socket IO Server (dużo kodu, ale działa). Wydaje się, że brakuje wsparcia dla Androida i IOS, jeśli chodzi o socket io, co jest tragedią.

Zasadniczo tworzenie nazwy pokoju poprzez dołączenie unikalnego identyfikatora użytkownika z mysql lub mongo, a następnie sortowanie go (wykonywane w kliencie Androida i wysyłane na serwer). więc każda para ma unikalną, ale wspólną nazwę pokoju pary. Więc pogadaj w tym pokoju.

Na szybka refernce jak pokój jest tworzony w Androidzie

 // Build The Chat Room
        if (Integer.parseInt(mySqlUserId) < Integer.parseInt(toMySqlUserId)) {
            room = "ic" + mySqlUserId + toMySqlUserId;
        } else {
            room = "ic" + toMySqlUserId + mySqlUserId;
        }

Pełne Prace

Pakiet Json

"dependencies": {
    "express": "^4.17.1",
    "socket.io": "^2.3.0"
  },
  "devDependencies": {
    "nodemon": "^2.0.6"
  }

Socket IO Server

app = require('express')()
http = require('http').createServer(app)
io = require('socket.io')(http)

app.get('/', (req, res) => {

    res.send('Chat server is running on port 5000')
})

io.on('connection', (socket) => {

    // console.log('one user connected ' + socket.id);

    // Join Chat Room
    socket.on('join', function(data) {

        console.log('======Joined Room========== ');
        console.log(data);

        // Json Parse String To Access Child Elements
        var messageJson = JSON.parse(data);
        const room = messageJson.room;
        console.log(room);

        socket.join(room);

    });

    // On Receiving Individual Chat Message (ic_message)
    socket.on('ic_message', function(data) {
        console.log('======IC Message========== ');
        console.log(data);

        // Json Parse String To Access Child Elements
        var messageJson = JSON.parse(data);
        const room = messageJson.room;
        const message = messageJson.message;

        console.log(room);
        console.log(message);

        // Sending to all clients in room except sender
        socket.broadcast.to(room).emit('new_msg', {
            msg: message
        });

    });

    socket.on('disconnect', function() {
        console.log('one user disconnected ' + socket.id);
    });

});

http.listen(5000, () => {

    console.log('Node app is running on port 5000')
})

Android Socket IO Class

public class SocketIOClient {

    public Socket mSocket;

    {
        try {
            mSocket = IO.socket("http://192.168.1.5:5000");
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }

    public Socket getSocket() {
        return mSocket;
    }
}

Aktywność Androida

public class IndividualChatSocketIOActivity extends AppCompatActivity {

    // Activity Number For Bottom Navigation Menu
    private final Context mContext = IndividualChatSocketIOActivity.this;

    // Strings
    private String mySqlUserId;
    private String toMySqlUserId;

    // Widgets
    private EditText etTextMessage;
    private ImageView ivSendMessage;

    // Socket IO
    SocketIOClient socketIOClient = new SocketIOClient();
    private String room;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);

        // Widgets
        etTextMessage = findViewById(R.id.a_chat_et_text_message);
        ivSendMessage = findViewById(R.id.a_chat_iv_send_message);

        // Get The MySql UserId from Shared Preference
        mySqlUserId = StartupMethods.getFromSharedPreferences("shared",
                                                              "id",
                                                              mContext);

        // Variables From Individual List Adapter
        Intent intent = getIntent();

        if (intent.hasExtra("to_id")) {

            toMySqlUserId = Objects.requireNonNull(Objects.requireNonNull(getIntent().getExtras())
                                                          .get("to_id"))
                                   .toString();
        }

        // Build The Chat Room
        if (Integer.parseInt(mySqlUserId) < Integer.parseInt(toMySqlUserId)) {
            room = "ic" + mySqlUserId + toMySqlUserId;
        } else {
            room = "ic" + toMySqlUserId + mySqlUserId;
        }

        connectToSocketIO();

        joinChat();

        leaveChat();

        getChatMessages();

        sendChatMessages();

    }

    @Override
    protected void onPause() {
        super.onPause();

    }

    private void connectToSocketIO() {

        socketIOClient.mSocket = socketIOClient.getSocket();
        socketIOClient.mSocket.on(Socket.EVENT_CONNECT_ERROR,
                                  onConnectError);
        socketIOClient.mSocket.on(Socket.EVENT_CONNECT_TIMEOUT,
                                  onConnectError);
        socketIOClient.mSocket.on(Socket.EVENT_CONNECT,
                                  onConnect);
        socketIOClient.mSocket.on(Socket.EVENT_DISCONNECT,
                                  onDisconnect);
        socketIOClient.mSocket.connect();
    }

    private void joinChat() {

        // Prepare To Send Data Through WebSockets
        JSONObject jsonObject = new JSONObject();

        // Header Fields
        try {

            jsonObject.put("room",
                           room);

            socketIOClient.mSocket.emit("join",
                                        String.valueOf(jsonObject));

        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

    private void leaveChat() {
    }

    private void getChatMessages() {

        socketIOClient.mSocket.on("new_msg",
                                  new Emitter.Listener() {
                                      @Override
                                      public void call(Object... args) {
                                          try {
                                              JSONObject messageJson = new JSONObject(args[0].toString());
                                              String message = String.valueOf(messageJson);

                                              runOnUiThread(new Runnable() {
                                                  @Override
                                                  public void run() {
                                                      Toast.makeText(IndividualChatSocketIOActivity.this,
                                                                     message,
                                                                     Toast.LENGTH_SHORT)
                                                           .show();
                                                  }
                                              });
                                          } catch (JSONException e) {
                                              e.printStackTrace();
                                          }
                                      }
                                  });
    }

    private void sendChatMessages() {

        ivSendMessage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String message = etTextMessage.getText()
                                              .toString()
                                              .trim();

                // Prepare To Send Data Thru WebSockets
                JSONObject jsonObject = new JSONObject();

                // Header Fields
                try {
                    jsonObject.put("room",
                                   room);

                    jsonObject.put("message",
                                   message);

                    socketIOClient.mSocket.emit("ic_message",
                                                String.valueOf(jsonObject));

                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        });
    }

    public Emitter.Listener onConnect = new Emitter.Listener() {
        @Override
        public void call(Object... args) {

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(IndividualChatSocketIOActivity.this,
                                   "Connected To Socket Server",
                                   Toast.LENGTH_SHORT)
                         .show();

                }
            });

            Log.d("TAG",
                  "Socket Connected!");
        }
    };

    private Emitter.Listener onConnectError = new Emitter.Listener() {
        @Override
        public void call(Object... args) {

            runOnUiThread(new Runnable() {
                @Override
                public void run() {

                }
            });
        }
    };
    private Emitter.Listener onDisconnect = new Emitter.Listener() {
        @Override
        public void call(Object... args) {

            runOnUiThread(new Runnable() {
                @Override
                public void run() {

                }
            });
        }
    };

}

Android Gradle

// SocketIO
implementation ('io.socket:socket.io-client:1.0.0') {
    // excluding org.json which is provided by Android
    exclude group: 'org.json', module: 'json'
}
 0
Author: DragonFire,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-19 10:19:22