godfat / rest-core

Various rest-builder middleware for building REST clients.
Apache License 2.0
57 stars 13 forks source link

EventSource vs WebSocket? #26

Open speedmax opened 7 years ago

speedmax commented 7 years ago

Hi Godfat,

It's good to see this project still going strong. The event source example looks pretty similar to a lot of the chat example they have with web sockets.

What is your thought on getting streaming response on the web these days? Some web API provides both WS and Rest API these days.

godfat commented 7 years ago

Thanks. I don't know if this project is still going strong, as I no longer use this on production therefore I miss the chance to battle test this by myself, but I'll certainly still work on this if something is popping up, like bug reports or something comes to my mind that I should improve.

For EventSource and WebSocket, I think it's pretty clear that WebSocket is for bidirectional communication. Therefore for things like realtime chat, realtime interaction, etc, we should probably just use WebSocket.

However, realtime streaming doesn't mean it must be bidirectional. Actually, most of the web apps only need to receive data from servers, and they don't need sending messages to the servers in realtime. In those cases, I believe we should just use SSE (Server sent events, i.e. EventSource) because it's way easier to implement and use (therefore less bugs).

Some might argue that WebSocket only needs one connection, while if we're using multiple SSE, we need multiple connections. This might be true in HTTP/1.1, but with the adoption of HTTP/2, I believe this is no longer the case.

However here comes reality check. As you can see, SSE is somehow newer and less supported. It's possible due to compatibility reason, we can't use SSE. Then basically we have no choice.

It's not clear to me which would win in the end, but I guess that's what we have currently.

speedmax commented 7 years ago

This is a example of creating a middleware/wsclient that follows similar interface that adds multiple sockets onto the same HTTP client object. This makes this class a more generalised HTTP/Web client for a specific online provider (Facebook, Twitter)

YourClient = RC::Builder.client do
  use RC::DefaultSite , 'https://api.github.com/users/'
  use RC::JsonResponse, true
  use RC::CommonLogger, method(:puts)

  use RC::WebSocket, "wss://ws.gitter.im/" # default URI (can be specified in instance method)
end

client = YourClient.new

es = client.event_source('users/tom.json', {}, # this is query, none here
                          :headers => {'Accept' => 'text/event-stream'})

# Instance of websocket using default URI
ws = client.websocket

ws.onopen{|s| s.write(subscribe: "tom_uid")}

# Stalker logic to reply to all tom's message
ws.onmessage{|s| s.write(message: "Yo Tom, It's me again") }

# Specify a different path or URI
ws1 = client.websocket("/activities")

ws2 = client.websocket("ws://www.host.com/chat")

Step 1

Early version could use Faye::Websocket as client

lib/rest-core/client/websocket.rb
lib/rest-core/middleware/websocket.rb

Step2

Ideally, the logic that handles EventEmitter and concurrency share the same underlying rest-core libs like promisepool and timer.

Use a generalised Websocket::Driver and without the weight from Faye::Websocket, Extend event_source and create common abstraction Server Side Event (1 way) and Websocket (bidirectional)

godfat commented 7 years ago

Do you have a working copy so that I could play around it a bit?

I would like to understand the use case a bit more. Would it be something like this?

ws1 = client.websocket("/activities")
ws2 = client.websocket("ws://www.host.com/chat")

ws1.puts "some message"
ws2.puts "some other message"

response1 = ws1.gets
response2 = ws2.gets
speedmax commented 7 years ago

@godfat No i don't have a working copy yet. I am messing with a lot of web and ws clients to learn more about these recent ruby projects and fundamental building blocks better. (concurrent-ruby, nio4r, websocket-driver).

@khoan and I will be doing dev around these areas, I will ping you when I have some working code.

godfat commented 7 years ago

Cool, thanks! Looking forward to it.