Open tleyden opened 6 years ago
I found another way to do this which is a bit more async (and I'm guessing more idiomatic).
SetNoReply(true)
:receivedFileWaitGroup
context := blip.NewContext()
sender, err := context.Dial(fmt.Sprintf("ws://localhost:%d/%s", DefaultPort, DefaultEndpoint), "http://localhost")
if err != nil {
panic("Error opening WebSocket: " + err.Error())
}
receivedFileWaitGroup := sync.WaitGroup{}
// If the server sends any requests with more files, handle them here.
context.HandlerForProfile[ProfileReceiveFile] = func(request *blip.Message) {
defer receivedFileWaitGroup.Done()
body, err := request.Body()
if err != nil {
response := request.Response()
response.SetError("CloudDrop", 0, fmt.Sprintf("Error reading request body in profile handler: %v. Error %v", ProfileListUsers, err))
return
}
log.Printf("Client just received incoming request! %s", body)
if response := request.Response(); response != nil {
response.SetBody([]byte("Generic Response"))
response.Properties["Content-Type"] = request.Properties["Content-Type"]
}
}
request := blip.NewRequest()
request.SetProfile(ProfileReceiveFile)
request.Properties["Content-Type"] = "application/octet-stream"
request.SetBody([]byte("username"))
request.SetNoReply(true)
sent := sender.Send(request)
if !sent {
panic(fmt.Sprintf("Could not send"))
}
receivedFileWaitGroup.Add(1)
// block until we get a file
receivedFileWaitGroup.Wait()
blipContext.HandlerForProfile[ProfileReceiveFile] = func(request *blip.Message) {
// The body contains the username
body, err := request.Body()
if err != nil {
response := request.Response()
response.SetError("CloudDrop", 0, fmt.Sprintf("Error reading username from request: %v", err))
return
}
// Simulate another client connecting, getting a handle to the sender, and creating a new outbound request to send the data
go func() {
log.Printf("Waiting 10 seconds to send request2")
time.Sleep(time.Second * 10)
request2 := blip.NewRequest()
request2.SetProfile(ProfileReceiveFile)
request2.Properties["Content-Type"] = request.Properties["Content-Type"]
request2.SetBody([]byte("request2 content"))
sent := request.Sender.Send(request2)
if !sent {
panic(fmt.Sprintf("Could not send"))
}
}()
I started building a simple file transfer app to get my hands dirty with blip.
and then ClientB pushes it's data to the server, which then pushes it down to clientA.
The way I was planning on implementing it was to have the server do the following when receiving a request from ClientA stating they are ready to receive a file:
Does the server blocking the ClientA response until ClientB shows up to send the file sound like a recommended way to do this? How long can I block in a request handler before the sending client disconnects with a timeout? Here is a code snippet that might give a more concrete idea of what I'm trying to do.
Also, how would I do this in a streaming fashion? For example, I see a
func (m *Message) BodyReader() (io.Reader, error)
method, but no equivalent streaming API for the response. I only see seefunc (m *Message) SetBody(body []byte)
which expects the entire body to be in memory.@snej Btw if there's a better place to ask these kinds of questions (forum? google group?), let me know. I just wanted it out of email so I can go find it later, and maybe get other blip experts to chime in!