-
-
Notifications
You must be signed in to change notification settings - Fork 52
The ask method
As we've seen on a part of the Getting Started section the client (or server) can also block/wait and catch a response from the remote side anywhere in the application flow, you are not limited to the asynchronous event-driven API. Both methods and styles are used in a typical, common, application.
Use this method when you have access to the connection value that you want to ask for.
The Conn.Ask
and NSConn.Ask
methods do exactly that.
In this section you will learn how to create a question-answer flow and how to manage incoming remote event errors, remember? Event callback can return an error
too.
At this example, for the shake of simplicity, we will set to a client the role to ask and server to reply, but this can be converted to a bidirectional flow too, each NSConn
and Conn
's method can be used by both server and client sides.
The application is fairly simple, the client will provide a date month-day-year
and server will reply back if its a work day or if the date is not valid for work, it's a day off or the provided time format is invalid.
Let's dive in by defining our server-side.
const namespace = "default"
var errDayOff = errors.New("day off")
func runServer() {
websocketServer := neffos.New(
gorilla.DefaultUpgrader,
neffos.Namespaces{
namespace: neffos.Events{
"workday": func(c *neffos.NSConn, msg neffos.Message) error {
date := string(msg.Body)
t, err := time.Parse("01-02-2006", date)
if err != nil {
return err
}
weekday := t.Weekday()
if weekday == time.Saturday || weekday == time.Sunday {
return errDayOff
}
responseText := fmt.Sprintf("it's %s, do your job.", weekday)
return neffos.Reply([]byte(responseText))
},
},
})
router := http.NewServeMux()
router.Handle("/", websocketServer)
log.Println("Serving websockets on localhost:8080")
log.Fatal(http.ListenAndServe(":8080", router))
}
Continue with our client-side.
func runClient() {
// Make the client error-aware of the `errDayoff`
// If that's missing the `Message.Err.Error() string` would still match it
// but comparison of err == errDayOff wouldn't be a valid one.
neffos.RegisterKnownError(errDayOff)
ctx := context.Background()
client, err := neffos.Dial(ctx,
gorilla.DefaultDialer,
"ws://localhost:8080",
// Empty events because client does not need an event callback in this case.
// The client is only uses the `Ask` method which allows the caller
// to manage the response manually even if a local event is not registered at all.
neffos.Namespaces{namespace: neffos.Events{}},
)
if err != nil {
panic(err)
}
c, err := client.Connect(ctx, namespace)
if err != nil {
panic(err)
}
fmt.Println("Please specify a date of format: mm-dd-yyyy")
for {
fmt.Print(">> ")
var date string
fmt.Scanln(&date)
response, err := c.Ask(ctx, "workday", []byte(date))
if err != nil {
if err == errDayOff {
// >> 06-29-2019
// it's a day off!
fmt.Println("it's a day off!")
} else {
// >> 13-29-2019
// error received: parsing time "13-29-2019": month out of range
fmt.Printf("error received: %v\n", err)
}
continue
}
// >> 06-24-2019
// it's Monday, do your job.
fmt.Println(string(response.Body))
}
}
Note that the error managment works the same way with the event-driven API too. Instead of response, [err] := c.Ask(...)
the err
error is stored at the incoming Message.Err
field, a quick view:
func onSomething(c *neffos.NSConn, msg neffos.Message) error {
if msg.Err != nil {
if msg.Err == errDayOff {
// [handle errDayoff...]
}
}
}
Read more at Errors section.
Use this method when you:
- do NOT have access to the connection value that you want to ask for or
- want to wait for a reply from a client that may be served by other neffos server (when your app is scaled-out).
The Server.Ask
method is like Server.Broadcast
but it blocks until response,
from a specific connection (when "msg.To"
is filled) or
from the first connection which will reply to this "msg"
.
- Accepts a context for deadline as its first input argument.
- The second argument is the request message which should be sent to a specific namespace:event like the
Conn/NSConn.Ask
.
Ask(ctx context.Context, msg Message) (Message, error)
Example Client Event:
"onAsk": func(c *neffos.NSConn, msg neffos.Message) error {
return neffos.Reply([]byte("I am fine"))
}
Usage
response, err := websocketServer.Ask(context.TODO(), neffos.Message{
// To: toConnID,
Namespace: namespace,
Event: "onAsk",
Body: []byte("how are you?"),
})
if err != nil {
// [handle err...]
}
response.Body would be []byte("I am fine")
.
Home | About | Project | Getting Started | Technical Docs | Copyright © 2019-2023 Gerasimos Maropoulos. Documentation terms of use.