Skip to content
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

Hub with Group #21

Closed
wilksmatt opened this issue Jun 4, 2013 · 29 comments
Closed

Hub with Group #21

wilksmatt opened this issue Jun 4, 2013 · 29 comments

Comments

@wilksmatt
Copy link

Hi,

Do you have an example of connecting to a group while using Hubs?

Thanks,

Matt

@wilksmatt
Copy link
Author

Hi,

We have a home automation platform and android application. It's essentially all done but there is one last item that I have not been able to get working which is receiving messages on the Android client with SignalR/A using hubs and groups. I haven't seen a complete example of what I'm explicitly trying to do so I'm interested in whether others might be experiencing the same issue or whether there is something obvious I can try debugging. Below I have included the main code blocks that I feel are relevant to explain my problem. It would be great if you a) take a look at my code to diagnose any obvious mistakes or b) share a working example of my scenario. Looking forward to your feedback and getting my app on the marketplace!

The following is the SignalR Hub we have implemented server side in dot net. It's a simple method to add the client to a group. It follows the specified SignalR design pattern. It's expected to be called by a client-side Invoke call. It is synchronous and returns void.

public class devices : Hub{
public void RegisterHome(string homeId)
{
Groups.Add(Context.ConnectionId, homeId);
}
}

The following is the Android SignalA hub connection code. It successfully connects to the server no problem and logs state changes. It creates a hub proxy and also creates a callback for one specific signalA message 'updateDeviceStatus'. When the signalR connection is 'connected' it attempts to add itself to a Group by invoking the 'RegisterHome' method above. I've successfully received signalR messages that are broadcasted to all connections but I cannot receive a message broadcasted to a group. I'm not getting errors so it's difficult to debug. I figure that I must be doing something wrong with either implementing the hub or group.

public void initializeSignalA(){

try {

        //SignalA Hub Connection
    con = new HubConnection(SIGNALRURL.toString(), this, new LongPollingTransport())
    {

        @Override
        public void OnError(Exception exception) {
            Log.e("SignalR State Error", exception.getMessage());
                    exception.printStackTrace();
        }

        @Override
        public void OnMessage(String message) {
            Log.i("SignalR Message", message);
        }

        @Override
        public void OnStateChanged(StateBase oldState, StateBase newState) {
            Log.i("SignalR State Changed", oldState.getState() + " to " + newState.getState());
            switch(newState.getState())
            {
                case Disconnected:                      
                    break;
                case Connected:
                    registerHome(); //Register the home ID once signalR is connected
                    break;
                case Connecting:
                    break;                      
                case Reconnecting:
                    break;  
                case Disconnecting:
                    break;                          
            }
        }
    };

    //Listen only for "devices" hub messages
    hub = con.CreateHubProxy("devices");

    //Listen for device updates
    hub.On("updateDeviceStatus", new HubOnDataCallback() 
    {
        @Override
        public void OnReceived(JSONArray args) {
            Log.i("SignalR Received", args.toString());
        }
    });                 

    //Start SignalA
    if(con!=null)
        con.Start();

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

}

The following method in my Android app calls the 'RegisterHome' method in the server side the SignalR hub. It calls and completes successfully but never invokes either of the callback methods OnError or OnResult. I don't know if I should be expecting one of those callback methods to execute since the 'RegisterHome' method returns void.

public void registerHome(){
ArrayList homes = new ArrayList(1);
homes.add(homeid);
hub.Invoke("RegisterHome", homes, new HubInvokeCallback()
{
@OverRide
public void OnError(Exception ex) {
Log.i("Register Home Error", ex.getMessage());
ex.printStackTrace();
}
@OverRide
public void OnResult(boolean succeeded, String result) {
Log.i("Register Home Result", result);
}
});
}

@erizet
Copy link
Owner

erizet commented Jun 14, 2013

Interesting and well explained!
Regarding to 'RegisterHome' calls don't get any callbacks, can you try and add a return value? Is the callbacks called then?

@wilksmatt
Copy link
Author

Hi,

Updated the server side method to return a boolean value:

public bool RegisterHome(string homeId)
{
try
{
Groups.Add(Context.ConnectionId, homeId);
return true;
}
catch (Exception ex)
{
return false;
}
}

My log now prints the following, which shows that the OnResult is being called.

06-15 04:04:32.902: V/ConnectedState(991): Message sent: {"H":"devices","A":["9db8dffd-d5df-4377-a29d-f523210fb019"],"M":"RegisterHome","I":"0"}
06-15 04:04:32.910: I/Register Home Result(991): true
06-15 04:04:32.910: V/HubProxy(991): Invoke of RegisterHomesent to devices

So this is a good indicator that the invoke and adding to the group is working successfully however my client is still not receiving signalR messages at all. Any other thoughts?

Thanks!

@erizet
Copy link
Owner

erizet commented Jun 20, 2013

I had a look at your problem....
I think you should make sure that a groupsToken is received. Place a breakpoint here
https://github.com/erizet/SignalA/blob/master/SignalA/src/com/zsoft/SignalA/Transport/TransportHelper.java#L42

then make sure that the groupstoken is sent back. Place a breakpoint here:
https://github.com/erizet/SignalA/blob/master/SignalA/src/com/zsoft/SignalA/Transport/TransportHelper.java#L108

@erizet
Copy link
Owner

erizet commented Jun 20, 2013

After your hub.invoke( bla, bla...) is run, check if you reach this code...
https://github.com/erizet/SignalA/blob/master/SignalA/src/com/zsoft/SignalA/Hubs/HubConnection.java#L38

@wilksmatt
Copy link
Author

Hi,

You led me me in the right direction. After debugging as per your instructions I discovered that all breakpoints are reached but that the groupsToken is returning null. Knowing that now, what do you suggest as next steps?

Thanks!

Matt

@erizet
Copy link
Owner

erizet commented Jun 25, 2013

When you reach...
https://github.com/erizet/SignalA/blob/master/SignalA/src/com/zsoft/SignalA/Transport/TransportHelper.java#L42
...can you print out response so we can look at it?

@wilksmatt
Copy link
Author

These are the variables at the time of the breakpoint. Is this what you were looking for? Sorry it isn't copy&pasting nicely into the comments.

groupsToken null
info null
messagesArray null
newMessageId "" (id=830013410304)
count 0
hashCode 0
offset 0
value (id=830013410336)
result ProcessResult (id=830016373840)
disconnected false
processingFailed false
timedOut false
connection MainActivity$3 (id=830016193624)
mCallbackId 1
mCallbacks HashMap (id=830016197016)
mConnectionId "2ba211fd-df32-4bd8-abff-321b1811488f" (id=830016201744)
mConnectionToken "O7WcW03bI-qSCK3786CFPQaCJYiIdBdt-VVriQBhr7Zua0xsQOfZd60c9PS2nDIaZoSHOV_4vnt1bL91L0sLCh1V1Lt-znp77iB-ccWxE4uxFNfiEJVSyCoTRIbn5NgojDPdTREdwXgFx_s1dl6A5tGLH-Y1" (id=830016219680)
mContext MainActivity (id=830015961904)
mCurrentState ConnectedState (id=830016193960)
mGroupsToken null
mHubs HashMap (id=830016196960)
mMessageId null
mStateLock Object (id=830016195160)
mTransport LongPollingTransport (id=830016195144)
mUrl "http://fakeurl.com/signalr" (id=830016197520)
this$0 MainActivity (id=830015961904)
response JSONObject (id=830016372664)
nameValuePairs HashMap (id=830016372720)
entryForNullKey null
entrySet HashMap$EntrySet (id=830016452832)
this$0 HashMap (id=830016372720)
entryForNullKey null
entrySet HashMap$EntrySet (id=830016452832)
keySet null
keySet null
modCount 2
size 2
table HashMap$HashMapEntry4
threshold 3
values null
valuesCollection null
keySet null
keySet null
modCount 2
size 2
table HashMap$HashMapEntry4
[0] null
[1] HashMap$HashMapEntry (id=830016373144)
[2] null
[3] HashMap$HashMapEntry (id=830016372936)
threshold 3
values null
valuesCollection null

@erizet
Copy link
Owner

erizet commented Jun 26, 2013

I need to know what,

response JSONObject (id=830016372664)

contains. I want to make sure that you're receiving a groupsToken. If not, there must be something wrong on the serverside....I think. :)

@wilksmatt
Copy link
Author

This image below is the data that I get back in the response object from the following method in the TransportHelper class:

public static ProcessResult ProcessResponse(ConnectionBase connection, JSONObject response)

group_token_response

@erizet
Copy link
Owner

erizet commented Jun 27, 2013

Run a few more times and see if you get something like this in response.

{"M":[],"T":1,"C":"B,4|I,0|J,0|K,0"}

@wilksmatt
Copy link
Author

I'm not finding this. On what variable should I find this response? Or more
specifically, is that the expected response of that "response" variable?

On Thu, Jun 27, 2013 at 3:37 PM, erizet notifications@github.com wrote:

Run a few more times and see if you get something like this in response.

{"M":[],"T":1,"C":"B,4|I,0|J,0|K,0"}


Reply to this email directly or view it on GitHubhttps://github.com//issues/21#issuecomment-20149532
.

@erizet
Copy link
Owner

erizet commented Jul 1, 2013

The "response" will vary. Run till you hit the breakpoint, check "respons", run again, check again and so on....

@wilksmatt
Copy link
Author

Okay thanks. On the sixth run I ended up getting that similar response. Here are the two responses that I get...

{"I":"0","R":true}

{"M":[],"T":1,"C":"B,0|g,0|h,0|i,0"}

@erizet
Copy link
Owner

erizet commented Jul 2, 2013

Since none of the responses contains G....it looks like your not in a group. As I understand this should the groups be sent to the client from the server and then will the client return the groups to the server in the next request....

@wilksmatt
Copy link
Author

Hi,

We know that our server-side code is working because we have other clients working successfully. We created a test server to help debug this issue. Using it with our Android app we are able to see the signalR message received when we broadcast to all clients but not when we broadcast to the specific group (obviously proving the fact that this is a groups problem). Do you think you can create a simple example Android app that uses hubs and groups using this test signalR server?

http://signalrgrouptest.azurewebsites.net/

Thanks a lot,

Matt

@wilksmatt
Copy link
Author

Any update? If anyone can get a simple app working with our sample signalR server (http://signalrgrouptest.azurewebsites.net/) that implements Hubs and broadcasts to a group then I'll give them a free year of service to our home control platform/app. Need to get this working ASAP to meet our August release deadline. Thanks.

@erizet
Copy link
Owner

erizet commented Jul 16, 2013

Could you please force your JS client to use longpolling? By doing that the traffic between your JS client and your SignalA client should be equivalent.
I think you need to specify the transport when you start your connection, like this:
connection.start({ transport: 'longPolling' });

@wilksmatt
Copy link
Author

Yes I can try to create new JS client that forces longpolling to compare. That said, have you ever been able to get an example working (with your own sample projects) that implments hubs with groups and longpolling? I would like to know whether the problem is specific to our system (.NET server + Android client) or the SignalA/Longpolling frameworks. Thanks a lot!

@erizet
Copy link
Owner

erizet commented Jul 18, 2013

I haven't tried to get groups working with hubs.
But if you give me a JS client that works with longpolling then I will be able to compare the traffic to a SignaA client. It should be identical...

@wilksmatt
Copy link
Author

Hi,

We updated the following SignalR Web server and client application to force using longpolling. Unfortunately I'm still experiencing same problem as before when connecting using the Android SignalA client.

http://signalrgrouptest.azurewebsites.net/

Also, I'm providing the complete source code of the sample .NET Web app for you to download and run locally:

https://skydrive.live.com/?cid=82172cd3cc3886fa&id=82172CD3CC3886FA%213250&authkey=!AMpJwCO2B1CSI0I

Is there anything else that you might need?

Thanks,

Matt

@erizet
Copy link
Owner

erizet commented Jul 20, 2013

Hi again,

I had a look at the traffic between the updated JS client and the server. The protocol has changed. I haven't noticed it before. I have to go through the .net code to see what is changed....

Regarding the behavior of the client when added to the group, it is as expected. After adding the client to a group a grouptoken is passed back and forth between the client and the server.

@wilksmatt
Copy link
Author

Great, glad you were able to find the root cause. When do you think you will be able to get to it? Thanks!

@wilksmatt
Copy link
Author

Make any progress? Thanks.

@erizet
Copy link
Owner

erizet commented Jul 31, 2013

I hope so. :) Please look at the new release. I have found a bug in the way SignalA was handling the groupstoken. It was overritten for each response from the server that didn't include a groupstoken. Hopefully it's fixed now.
I've also included a new sample, 'HubGroupDemo'. It connects to your website. Have a look!

@wilksmatt
Copy link
Author

The good news is that the demo works now! I did run into one snag though... joining a group doesn't always work when it's attempted pragmatically after signalR is "Connected". What my app tries to do is join a group right after signalR successfully connects. I don't want the user to manually join a group. It works all the time when there is a button in the app to join a group. I figure this is because there is a conflict with joining a group too soon after a signalR connection. What do you think?

@erizet
Copy link
Owner

erizet commented Aug 12, 2013

One more try... :)
I've made a new version in which I changed when the statechanged event is fired. Now the event is fired AFTER the new state is run. It looks to solve your problem.

@wilksmatt
Copy link
Author

Yes!! You made me happy guy. With that fix, our home control Android app is complete. Will be going on the Play store soon. Here's our website: http://homeboy.in/

@erizet
Copy link
Owner

erizet commented Aug 14, 2013

Great! Please send me link to your app when it's up on Play store!

@erizet erizet closed this as completed Aug 14, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants