mashupbots / socko

A Scala web server powered by Netty networking and AKKA processing.
Other
255 stars 51 forks source link

I can't handler CloseWebSocketFrame event #71

Closed marsxu1984 closed 10 years ago

marsxu1984 commented 10 years ago

I check the code, CloseWebSocketFrame had been handle in socko framework. And I can't get any connect close event.

/home/mars/project/socko/socko-webserver/src/main/scala/org/mashupbots/socko/webserver/RequestHandler.scala Line 136. if (wsFrame.isInstanceOf[CloseWebSocketFrame]) { // This will also close the channel wsHandshaker.close(ctx.channel, wsFrame.asInstanceOf[CloseWebSocketFrame]) } else if (wsFrame.isInstanceOf[PingWebSocketFrame]) { ctx.writeAndFlush(new PongWebSocketFrame(wsFrame.content)) } else { server.routes(event) }

close event won't call server router

so, how can I handler close event without changing any code?

veebs commented 10 years ago

OK. We'll look at this for the next release.

timothyhahn commented 10 years ago

Hey, firstly I'd love to say the library is great and I'm enjoying using it so far. I know you're probably busy on getting Netty 4 integrated, but do you have an idea of when you'll have a fix for this? Or a workaround that can be used for now? I feel like knowing extremely quickly whether a client has disconnected or not is really important, and in the mean time I haven't been able to come up with any alternatives that give us back this information in a passable amount of time.

Again, thanks for your work so far. It really has been easy to work with, aside from this one issue.

veebs commented 10 years ago

Sorry for being slow on this ... my day job has been hectic again.

I am having time off over Christmas/new year. I'll get back to socko then.

Part of the problem with this issue is that to tell you a connection is closed, we have to identify it first. I was hoping netty would bring back a channel id - but that was implemented for a future release. Looks like for netty 4, we'll have to invent our own id.

Will passing a message with an id (when the channel connects or disconnects) to your nominated actor work for you?

On 13 Dec 2013, at 2:37 am, Timothy Hahn notifications@github.com wrote:

Hey, firstly I'd love to say the library is great and I'm enjoying using it so far. I know you're probably busy on getting Netty 4 integrated, but do you have an idea of when you'll have a fix for this? Or a workaround that can be used for now? I feel like knowing extremely quickly whether a client has disconnected or not is really important, and in the mean time I haven't been able to come up with any alternatives that give us back this information in a passable amount of time.

Again, thanks for your work so far. It really has been easy to work with, aside from this one issue.

— Reply to this email directly or view it on GitHub.

timothyhahn commented 10 years ago

Understood, I thought that was probably the case.

That seems like that should work. The id is your own implemented channel id?

veebs commented 10 years ago

Yes - I'm thinking when a channel connects, I have to add it to a map with an id (guid). I'll also save the id in the channel so that I can access the id upon disconnect.

On 13 December 2013 06:47, Timothy Hahn notifications@github.com wrote:

Understood, I thought that was probably the case.

That seems like that should work. The id is your own implemented channel id?

— Reply to this email directly or view it on GitHubhttps://github.com/mashupbots/socko/issues/71#issuecomment-30455198 .

veebs commented 10 years ago

All web socket connections now stored in webserver.webSocketConnections.

You can use webserver.webSocketConnections.isConnected(myWebSocketId) to check if a connection is connected or closed.

You can also pass a callback function to authorise() that will be called when the connection is closed.

val routes = Routes({
  case WebSocketHandshake(wsHandshake) => wsHandshake match {
    case Path("/websocket/callbacks/") => {
      wsHandshake.authorize(onComplete = Some(testOnCompleteCallback), onClose = Some(testOnCloseCallback))
    }
  }
  case WebSocketFrame(wsFrame) => {
    val name = "SnoopHandler_%s_%s".format(wsFrame.context.name, System.currentTimeMillis)
    actorSystem.actorOf(Props[SnoopHandler], name) ! wsFrame
  }
})

def testOnCompleteCallback(webSocketId: String) {
  System.out.println(s"Web Socket $webSocketId connected")
}

def testOnCloseCallback(webSocketId: String) {
  System.out.println(s"Web Socket $webSocketId closed")
}
marsxu1984 commented 10 years ago

Thanks,Veebs. I glad you DID SO MUCH for this issus.