GoFBP Sample WebSockets Components

The GoFBP WebSockets support works very similarly to the corresponding JavaFBP facilities - see JavaFBP - esp. the diagrams at the end.

This facility (two components in GoFBP WebSockets ) may be thought of as a "kit" for building a wide variety of WebSocket applications. "request.go" fields requests from a client, while "respond.go" returns results back to the same user. Both of these components use the FBP "substream" concept, where a substream is a series of Information Packets ("IPs"), surrounded by "bracket IPs" ("open" and "close"). "request.go" emits a series of substreams, each of which represents a "send" from the client, while "respond.go" expects a series of substreams, each of which will result in an HTML display. In between these two components may be a network of any degree of complexity... except that care must of course be taken to ensure that the IPs of a given substream not be allowed to become separated. If this is a problem, substreams can be converted to FBP "tree" structures.

Eah substream comprises an "open bracket IP", followed by an IP referencing the WebSocket "Conn" struct, in turn followed by zero or more data IPs, followed by a "close bracket".

Here is the "processing" component for this very simple test case (I will assume that you are familiar with how to build a GoFBP component). It is a standard "looper" style of component, where substreams are consumed and emitted until "Receive" returns a packet reference of "nil" :

package components

import (
	"github.com/jpaulm/gofbp/core"
)

type WSAnsReq struct {
	ipt core.InputConn
	out core.OutputConn
}

func (wsansreq *WSAnsReq) Setup(p *core.Process) {
	wsansreq.ipt = p.OpenInPort("IN")
	wsansreq.out = p.OpenOutPortOptional("OUT")
}

func (WSAnsReq) MustRun() {}

func (wsansreq *WSAnsReq) Execute(p *core.Process) {
	pkt := p.Receive(wsansreq.ipt)
	for {

		if pkt == nil {
			break
		}
		p.Send(wsansreq.out, pkt)  // this will be an open bracket

		pkt = p.Receive(wsansreq.ipt) // connection
		p.Send(wsansreq.out, pkt)

		pkt = p.Receive(wsansreq.ipt) //"namelist"
		p.Discard(pkt)

		pkt = p.Create("line1")
		p.Send(wsansreq.out, pkt)
		pkt = p.Create("line2")
		p.Send(wsansreq.out, pkt)
		pkt = p.Create("line3")
		p.Send(wsansreq.out, pkt)

		pkt = p.Receive(wsansreq.ipt) // emit close bracket
		p.Send(wsansreq.out, pkt)

		pkt = p.Receive(wsansreq.ipt)  // now test if a @kill was received: if not, go get next substream
		if pkt.PktType == core.Signal && pkt.Contents.(string) == "@kill" {
			p.Send(wsansreq.out, pkt)
			pkt = p.Receive(wsansreq.ipt)
		}
	}

}

This will output a substream for every substream it receives. Two more points:

Every process in the server network must do these two things.