ClusterWS/ClusterWS-Client-Java

socket.send

Closed this issue · 25 comments

Submitting

  • Bug
  • Question
  • Suggetion
  • Other

Details

hi
I use the following code to watch from channel:

ClusterWS socket ;
oncreate (){
     initChat();
}
  private void initChat() {
    socket = new ClusterWS("url");
    socket.connect();
    socket.setReconnection(true, 2, 10, 20);

    socket.setClusterWSListener(new IClusterWSListener() {
      @Override
      public void onConnected() {
        Channel channel = socket.subscribe("match-wall");
        channel.watch(new Channel.IChannelListener() {
          @Override
          public void onDataReceived(String channelName, Object data) {
            Gson gson = new Gson();
            String json = gson.toJson(data);
            try {
              JSONObject object = new JSONObject(json);
              String action = object.getString("action");
              if (action.equals("publish")) {
                String username = object.getString("username");
                String message = object.getString("message");
                String photo = object.getString("photo");
                addMessage(username, message, photo);
              } else if (action.equals("number-of-users")) {
                //Todo
              }
            } catch (JSONException e) {
              e.printStackTrace();
            }

          }
        });
      }

      @Override
      public void onError(Exception exception) {
      }

      @Override
      public void onDisconnected(int code, String reason) {
      }
    });
  }

and this code to send data to server:

private void sendMessage() {
    hideKeyboard();
    String message = edtChatMsg.getText().toString().trim();
    if (TextUtils.isEmpty(message)) {
      edtChatMsg.requestFocus();
      return;
    }
    edtChatMsg.setText("");

    final JSONObject jsonObject = new JSONObject();
    try {
      jsonObject.put("username", mUsername);
      jsonObject.put("message", message);
    } catch (JSONException e) {
      e.printStackTrace();
    }

    Channel channel = socket.getChannelByName("match-wall");
    if (channel != null) {
      socket.send("match-wall-send-message", jsonObject.toString());
    } 
  }

but socket.send not working.....
I am sincerely thankful.

I also have same problem. Please resolve the issue as soon as possible.

@mojtaba391 @amirzandi from what I understand you want to send data to the channel. If you want to send the data through the channel you have to use the different method which is channel.publish("any-data-you-want"); Also make sure you are connected to socket when you are sending the data. Tell me if this resolves your issue

One question. While we call channel.publish, does it send message to sever or it directly broadcast message to clients joint to that channel?

Message is broadcasted to the clients which joined to the channel, there are a way to catch message on the server. If u use standard send event that should send message only to the server and in case if you want to broadcast from the server to the channels u should use publish method on the server.

Check this Guide for the publish from the serve to the channels. In case if you want to just send message back to the client (not to many clients) use standard send method.

It is working in Swift code but it is not working on Android. Here is our code:
Channel channel = socket.getChannelByName("match-wall");
if (channel != null) { socket.send("match-wall-send-message", jsonObject.toString()); }

If i understand right this line socket.send("match-wall-send-message", jsonObject.toString()); sends data to the server ? Can u share code which u have on the server for match-wall-send-message event part ?

It is working fine at ios, we do only have problem with Android version.

Ok @Yegorisa can we check it out ?

Any news?

@Yegorisa Any updates?

@amirzandi I will take a look at it today

@amirzandi I have tested the socket.send("any", jsonObject.toString()); method and it is working fine. I attached screenshots of implementation. Could you please provide more details?
screen shot 2018-09-07 at 10 09 55 am
screen shot 2018-09-07 at 10 09 43 am

@amirzandi @mojtaba391 @goriunov here is the code for the Android and server. All data is sent and received. Also recommended way of using Socket on Android is to use it on different thread. Tell me if this helps! If this does not help you neeed to provide more code for server and client(Android) and steps how to reproduce the problem.

public class Test1 extends AppCompatActivity {
    ClusterWS socket;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initChat();
    }

    private void initChat() {
        socket = new ClusterWS("ws://10.0.2.2:3000");
        socket.setReconnection(true, 2, 10, 20);
        socket.setClusterWSListener(new IClusterWSListener() {
            @Override
            public void onConnected() {
                Channel channel = socket.subscribe("match-wall");
                channel.watch(new Channel.IChannelListener() {
                    @Override
                    public void onDataReceived(String channelName, Object data) {
                        System.out.println("DATA IS " + data);
                    }
                });
                sendMessage();
            }

            @Override
            public void onError(Exception exception) {
            }

            @Override
            public void onDisconnected(int code, String reason) {
            }
        });
        socket.connect();
    }

    private void sendMessage() {
        final JSONObject jsonObject = new JSONObject();
        try {
            jsonObject.put("username", "");
            jsonObject.put("message", "");
        } catch (JSONException e) {
            e.printStackTrace();
        }

        Channel channel = socket.getChannelByName("match-wall");
        if (channel != null) {
            socket.send("match-wall-send-message", jsonObject.toString());
        }
    }
}
const ClusterWS = require('clusterws');
const express = require('express');

// Configure ClusterWS for more infor look at the bottom of https://github.com/ClusterWS/ClusterWS/wiki/Installation-and-Configuration
const clusterws = new ClusterWS({
  worker: Worker,
  port: 3000
});

function Worker() {
  const wss = this.wss;
  const server = this.server;

  const app = express();
  app.use(express.static('public'));

  server.on('request', app);

  // Check https://github.com/ClusterWS/ClusterWS/wiki/Handle-Sockets for more info
  // Most of websocket messaging code will go in this block
  wss.on('connection', (socket) => {
    console.log('New socket is connected');

    /* 
      This is the way how we send messages to front end websocket which is connected
      to this server,

      socket.send(nameOfEvent, message)
      
      (you can send any type of data you would like)
    **/
    socket.send('greet', 'Hi frontend i am backend how are you');

    /* 
      This is the way how we listen on events (the same way we use on frontend to listen)

      socket.on(nameOfEvent, callbackFunction)
    **/
    socket.on('match-wall-send-message', (message) => {
      wss.publish("match-wall", "Message from publish");
      console.log(message);
    });
  });
}

Also your order of code is wrong here

    socket = new ClusterWS("url");
    socket.connect();
    socket.setReconnection(true, 2, 10, 20);

    socket.setClusterWSListener(new IClusterWSListener() {

Connect must be the last. Otherwise connection might appear before you set the listeners.

@Yegorisa @goriunov this is full code of java but socket.send not working.please check and resolve my problem.
chat1
chat2
chat3

@mojtaba391 We also need server code (part which is responsible for publishing event to the channel) as wee need to able to reproduce that problem.

@goriunov here is the code of server. It is working correctly with iOS:

const User_Entity = require('../../../../models/User_Entity');
const WebSocket = require('ws');

module.exports = ((wss) => {
    var mainWallUsersCounter = 0;
    var waitWallUsersCounter = 0;
    var matchWallUsersCounter = 0;


    wss.setMiddleware('onUnsubscribe', (socket, channel) => {
        if(channel == 'main-wall') {
            var obj = {
                channel : channel,
                action: 'unsubscribe'
            };
            wss.publishToWorkers(obj);
            setTimeout(() => {
                var obj = {
                    action: 'number-of-users',
                    counter: mainWallUsersCounter
                };
                wss.publish('main-wall', obj);
            }, 300);
        }
        else if(channel == 'wait-wall') {
            var obj = {
                channel: channel,
                action: 'unsubscribe'
            };
            wss.publishToWorkers(obj);
            setTimeout(() => {
                var obj = {
                    action: 'number-of-users',
                    counter: waitWallUsersCounter
                };
                wss.publish('wait-wall', obj);
            }, 300);
        }
        else if (channel == 'match-wall') {
            var obj = {
                channel: channel,
                action: 'unsubscribe'
            };
            wss.publishToWorkers(obj);
            setTimeout(() => {
                var obj = {
                    action: 'number-of-users',
                    counter: matchWallUsersCounter
                };
                wss.publish('match-wall', obj);
            }, 300);
        }
    });

    wss.setMiddleware('onSubscribe',(socket, channel, next) => {
        if(channel == 'main-wall') {
            var obj = {
                channel: channel,
                action: 'subscribe'
            }
            wss.publishToWorkers(obj);
            setTimeout(() => {
                var obj = {
                    action: 'number-of-users',
                    counter: mainWallUsersCounter
                };
                wss.publish('main-wall', obj);
            }, 300);
        }
        else if(channel == 'wait-wall') {
            var obj = {
                channel: channel,
                action: 'subscribe'
            }
            wss.publishToWorkers(obj);
            setTimeout(() => {
                var obj = {
                    action: 'number-of-users',
                    counter: waitWallUsersCounter
                };
                wss.publish('wait-wall', obj);
            }, 300);
        }
        else if(channel == 'match-wall') {
            var obj = {
                channel: channel,
                action: 'subscribe'
            }
            wss.publishToWorkers(obj);
            setTimeout(() => {
                var obj = {
                    action: 'number-of-users',
                    counter: matchWallUsersCounter
                };
                wss.publish('match-wall', obj);
            }, 300);
        }
        next(true);
    });

    wss.setMiddleware('verifyConnection', (info, next) => {
        next(true);
    });

    wss.setMiddleware('onMessageFromWorker', (data) => {
        if(data.channel == 'main-wall') {
            if(data.action == 'unsubscribe') {
                mainWallUsersCounter--;
            }
            else if (data.action == 'subscribe') {
                mainWallUsersCounter++;
            }
        }
        else if(data.channel =='wait-wall') {
            if (data.action == 'unsubscribe') {
                waitWallUsersCounter--;
            } else if (data.action == 'subscribe') {
                waitWallUsersCounter++;
            }
        }
        else if(data.channel == 'match-wall') {
            if (data.action == 'unsubscribe') {
                matchWallUsersCounter--;
            } else if (data.action == 'subscribe') {
                matchWallUsersCounter++;
            }
        }
    });

    wss.setMiddleware('onPublish', (channel, data) => {

    });

    //set watchers
    wss.setWatcher('main-wall', (message) => { });
    wss.setWatcher('wait-wall', (message) => { });
    wss.setWatcher('match-wall', (message) => { });


    //handle connection
    wss.on('connection', (ws) => {
        ws.on('main-wall-send-message', data => {
            User_Entity().findOne({
                where: {
                    username: data.username
                }
            }).then(user => {
                var output = {};
                output.username = data.username;
                output.message = data.message;
                output.photo = user.dataValues.profile_photo;
                output.action = "publish";
                wss.publish('main-wall', output);
            });
        });

        ws.on('wait-wall-send-message', data => {
            User_Entity().findOne({
                where: {
                    username: data.username
                }
            }).then(user => {
                var output = {};
                output.username = data.username;
                output.message = data.message;
                output.photo = user.dataValues.profile_photo;
                output.action = "publish";
                wss.publish('wait-wall', output);
            });
        });

        ws.on('match-wall-send-message', data => {
            User_Entity().findOne({
                where: {
                    username: data.username
                }
            }).then(user => {
                var output = {};
                output.username = data.username;
                output.message = data.message;
                output.photo = user.dataValues.profile_photo;
                output.action = "publish";
                wss.publish('match-wall', output);
            });
        });

        //handle disconnect
        ws.on('disconnect', (code, reason) => {
            if(ws.channels['main-wall'] == 1 ) {
                mainWallUsersCounter--;
                setTimeout(() => {
                var obj = {
                    action: 'number-of-users',
                    counter: mainWallUsersCounter
                };
                wss.publish('main-wall', obj);
            }, 300);
            }

            if(ws.channels['wait-wall'] == 1 ) {
                waitWallUsersCounter--;
                setTimeout(() => {
                    var obj = {
                        action: 'number-of-users',
                        counter: waitWallUsersCounter
                    };
                    wss.publish('wait-wall', obj);
                }, 300);
            }
            if(ws.channels['match-wall'] == 1) {
                matchWallUsersCounter--;
                setTimeout(() => {
                    var obj = {
                        action: 'number-of-users',
                        counter: matchWallUsersCounter
                    };
                    wss.publish('match-wall', obj);
                }, 300);
            }
        });
    });
});

@amirzandi Server code seems to be alright, also @Yegorisa checked java code (i not sure if it has any problems), he will response with more details today.

@mojtaba391 hey I tried to reproduce the problem but I did not manage to do it. You can try to send not on main thread. Simple example is to use AsyncTask ->

        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                ClusterWS clusterWS = new ClusterWS("ws://localhost:3000");
                clusterWS.connect();
                clusterWS.send("testEvent","message");
            }
        });

Also make sure that you are connected to the server before sending requests

@Yegorisa @goriunov @amirzandi
I want to send the data to the channel...
I sent the full code on the screenshot.The sendMessage method is available in screenshot number three.
Please check the screenshots carefully.

Please note that we already have passed our deadline and the only part left is related to this issue. Therefore please take care of this issue as a high priority in your work load.

Thanking you in advance

@mojtaba391 Please note that it is Open Source project and we are no required to solve your problems and bugs.

As above stated. We have performed all the testes and have not found any issues in the communication between server and client (note all tests are executed on localhost).

To help you with your problem we need to be able to reproduce the issue and unfortunately we can not. Would be good if you could create simple (minimal repo) with server and client which reproduces exact behaviour.

@goriunov Thank you for your great support and reviewing our codes, though it is an open source library.
We eventually resolved the problem which was related to passing JSONObject to server, we found out that it only works with HashMap objects.

For those who faced to same problem, this component is only works while you pass HashMap objects to server.

@goriunov @Yegorisa thank you guys for all the great supports.

You may close this issue as well.

Great to hear that you were able to fix that bug :)

@amirzandi @Yegorisa will deploy new version of the library soon to fix some minor bug (not related to your issue) i would suggest to update to that version right away :)

@amirzandi @mojtaba391 by the way new version was released which is 3.0.2 which involves some minor bug fixes. I recommend to upgrade to this version

@Yegorisa thankyou.