Search code examples
javagoogle-app-enginechannel-api

Google App Engine UserServiceget.CurrentUser() returns null in servlet handling channel connect at /_ah/channel/connected/


I use Google Channel api and registered servlet at adreess /_ah/channel/connected/ to handle user channel connects. When connection happens in post message handler I find out that UserServiceget.CurrentUser() returns null, while in other servlets of my application it returns user. What is the case tell me please. The servlet code is like this:

@SuppressWarnings("serial")
public class ConnectServlet extends HttpServlet {
    @Override
    public void doPost(HttpServletRequest req, HttpServletResponse resp)
                    throws IOException {
        UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();

        if( user != null ){        
        String user_name = user.getNickname();
        Logger.getLogger("server").log( Level.WARNING, "User " + user_name + "  connected" );
       }
    }
}

security-constraint is:

<security-constraint>
    <web-resource-collection>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>*</role-name>
    </auth-constraint>
</security-constraint>

Solution

  • The call to /_ah/channel/connected/ is made by an internal Google Channel service server, not by user directly. So this request does not have user associated with it.

    This is an example how to handle Channel API:

    1. Server: Create a unique Client ID on the server. You can use user id:

      String clientId = userService.getCurrentUser().getUserId();
      
    2. Server: Create channel token from the Client ID and pass it back to client side:

      ChannelService channelService = ChannelServiceFactory.getChannelService();
      String token = channelService.createChannel(clientId);
      
    3. Use token in Javascript on client side:

      // --token-- a token received from server
      channel = new goog.appengine.Channel('--token--');
      
    4. Then in /_ah/channel/connected/ handler you can do:

      ChannelService channelService = ChannelServiceFactory.getChannelService();
      ChannelPresence presence = channelService.parsePresence(req);
      String clientId = presence.clientId();
      // clientId equals userId as set in point 1.