casualjim
11/9/2011 - 9:37 AM

gistfile1.md

class HomeWebServer extends BaseWebServer("HomeWebServer") {

  override def configWebServer {
    val meteorHolder  = new ServletHolder(new org.atmosphere.cpr.MeteorServlet)
    meteorHolder.setInitParameter("org.atmosphere.servlet", "org.yourpackage.AtmosphereMeteor")
    context.addServlet(meteorHolder, "/socket/*")
    context.addServlet(new ServletHolder(new Router), "/*")
  }
}

06:52 jakedouglas: [23:22:23] hmm. the example atmosphere code doesn't really click with me
06:52 casualjim: [23:22:34] yes because it's input and output
06:52 casualjim: [23:23:31] i'll map lines
06:52 casualjim: [23:23:33] https://github.com/scalatra/scalatra/blob/develop/example/src/main/scala/org/scalatra/ChatServlet.scala#L13
06:52 casualjim: [23:23:46] https://github.com/scalatra/scalatra/blob/develop/example/src/main/scala/org/scalatra/MeteorChatExample.scala#L53
06:52 casualjim: [23:23:53] that's the same point in the lifecycle
06:52 casualjim: [23:24:11] https://github.com/scalatra/scalatra/blob/develop/example/src/main/scala/org/scalatra/ChatServlet.scala#L22-36
06:52 casualjim: [23:24:27] https://github.com/scalatra/scalatra/blob/develop/example/src/main/scala/org/scalatra/MeteorChatExample.scala#L59-78
06:52 casualjim: [23:24:46] the "success" is just to force flushing the buffer it never arrives in the browser
06:52 casualjim: [23:25:14] https://github.com/scalatra/scalatra/blob/develop/example/src/main/scala/org/scalatra/MeteorChatExample.scala#L55
06:52 casualjim: [23:25:45] suspending the request makes it so the transport is used for the server push transport
06:52 casualjim: [23:26:01] the broadcast method is how you send stuff to the browser
06:52 jakedouglas: [23:26:31] they call it broadcast instead of "send" or "sendMessage" or something?
06:52 casualjim: [23:26:35] yes
06:52 casualjim: [23:27:15] because you can associate a connection/broadcaster (the thing is wrapped in a meteor instance) with either a connection, a path or something else i forget
06:52 casualjim: [23:27:36] but it means it's not necessarily to a single connection it can be a broadcast to many listeners
06:52 jakedouglas: [23:28:09] i see
06:52 casualjim: [23:28:14] I should have made an example with a custom broadcaster
06:52 jakedouglas: [23:28:57] is the post("/?*") { … } actually a new http post every time the client sends something? or it just appears that way
06:52 casualjim: [23:28:58] https://github.com/Atmosphere/atmosphere/blob/master/samples/jquery-meteor-pubsub/src/main/java/org/atmosphere/samples/pubsub/MeteorPubSub.java
06:52 casualjim: [23:29:07] it's a new post
06:52 casualjim: [23:29:20] you maintain the "socket" session with the meteor thing
06:52 jakedouglas: [23:29:20] a new connection?
06:52 casualjim: [23:29:28] that is stored in the session
06:52 casualjim: [23:29:33] or at least in the example
06:52 casualjim: [23:29:40] the meteor is what binds all together
06:52 jakedouglas: [23:30:05] hmm. so its a persistent connection but to the scalatra servlet it looks like different requests?
06:52 casualjim: [23:31:46] yes
06:52 casualjim: [23:31:54] that's also the case with socketio but it's hidden
06:52 casualjim: [23:32:01] because you only deal with the client socket
06:52 jakedouglas: [23:32:05] right
06:52 casualjim: [23:32:10] it has to be that way for anything but websockets
06:52 casualjim: [23:32:20] the nature of http
06:52 casualjim: [23:32:36] https://github.com/Atmosphere/atmosphere/blob/master/extras/xmpp/src/main/java/org/atmosphere/plugin/xmpp/XMPPBroadcaster.java
06:52 casualjim: [23:32:42] that's an example broadcaster
06:52 jakedouglas: [23:32:54] but just like in websockets i can store the Meteor somewhere and send to it whenever i want?
06:52 casualjim: [23:32:54] you can tie one of those guys to a path or connection
06:52 casualjim: [23:33:02] yes
06:52 jakedouglas: [23:33:07] k
06:52 casualjim: [23:33:14] I believe it's thread-safe
06:52 jakedouglas: [23:34:37] so would it be possible to make a more declarative wrapper like socketio?
06:52 casualjim: [23:35:11] it sure would
06:52 jakedouglas: [23:35:20] cool
06:52 casualjim: [23:35:48] while doing that I think you also want to implement heartbeating in the form of pingpong to clear out dangling connections
06:52 casualjim: [23:35:56] and appease haproxy and the like
06:52 jakedouglas: [23:36:36] i see. they would just hang around otherwise until tcp timeout or something?
06:52 casualjim: [23:37:00] yes but your web session might also still be active or you may want to do clean up
06:52 casualjim: [23:37:30] ping pong in those situations is generally a good idea :)
06:52 casualjim: [23:37:42] it's even baked into the websocket protocol now
06:52 jakedouglas: [23:37:55] right, i see. the MeteorChatExample essentially has an onConnect and onMessage, but no onClose or similar
06:52 casualjim: [23:38:03] the onclose
06:52 casualjim: [23:38:18] I think is when you resume the request
06:52 casualjim: [23:38:21] more or less
06:52 casualjim: [23:38:29] there is something that functions as ondisconnect
06:52 casualjim: [23:38:39] but it's been a while since I looked at those things
06:52 jakedouglas: [23:39:09] when you resume the request…don't understand
06:52 casualjim: [23:39:15] the general idea is that you are still in 1 and the same request (from the client POV)
06:52 casualjim: [23:39:29] on the server you suspend the request to pause it
06:52 casualjim: [23:39:45] it parks it in a queue sort of
06:52 jakedouglas: [23:40:02] i see. it just tells it to hold off on responding so you can do as you please with it.
06:52 casualjim: [23:40:06] and when you do a broadcast you resume the request (enabling it's output stream)
06:52 casualjim: [23:40:12] yes
06:52 casualjim: [23:40:17] if you then don't resume
06:52 casualjim: [23:40:34] sorry suspend again
06:52 casualjim: [23:40:48] then the request finishes and the connection is released
06:52 jakedouglas: [23:41:28] right. so in the MeteorChatExample, is the connection being released in the post() { … } ? i don't see another suspend there.
06:52 casualjim: [23:41:30] there is also this
06:52 casualjim: [23:41:31] https://github.com/scalatra/scalatra/blob/develop/example/src/main/scala/org/scalatra/MeteorChatExample.scala#L11-31
06:52 casualjim: [23:41:51] the broadcast does suspend/resume internally
06:52 jakedouglas: [23:41:55] oh, ok
06:52 casualjim: [23:42:09] in the post I broadcast to all connections but my own
06:52 casualjim: [23:42:30] you can also do a lot of stuff in the event listeners
06:52 jakedouglas: [23:44:14] is onBroadcast when i broadcast something to the client, or when the server receives something from the client?
06:52 *savebuff: 1320795855 ornicar!~ornicar@78.223.53.199 QUIT Read error: Connection reset by peer
06:52 casualjim: [23:44:29] that I don't remember exactly
06:52 casualjim: [23:44:40] but if you run the sample you'll see
06:52 jakedouglas: [23:44:46] k