Request-Response architecture

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.

The Conn Ask

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.

Create & run the Server

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))
}

Create & run the Client

Continue with our client-side.

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:

Read more about Errors.

The Server Ask

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".

  1. Accepts a context for deadline as its first input argument.

  2. The second argument is the request message which should be sent to a specific namespace:event like the Conn/NSConn.Ask.

Example Client Event:

Usage

response.Body would be []byte("I am fine").

Last updated