Skip to content

Commit

Permalink
Merge branch 'lorenzodonini:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
xBlaz3kx authored Mar 6, 2024
2 parents c285716 + c85a755 commit 884877e
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 1 deletion.
8 changes: 8 additions & 0 deletions ocpp2.0.1/charging_station.go
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,14 @@ func (cs *chargingStation) Start(csmsUrl string) error {
return err
}

func (cs *chargingStation) StartWithRetries(csmsUrl string) {
// Start client
cs.stopC = make(chan struct{}, 1)
cs.client.StartWithRetries(csmsUrl)
// Async response handler receives incoming responses/errors and triggers callbacks
go cs.asyncCallbackHandler()
}

func (cs *chargingStation) Stop() {
cs.client.Stop()
}
Expand Down
7 changes: 7 additions & 0 deletions ocpp2.0.1/v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,13 @@ type ChargingStation interface {
//
// No auto-reconnect logic is implemented as of now, but is planned for the future.
Start(csmsUrl string) error

// Connects to the CSMS and starts the charging station routine, it retries if first attempt fails.
// The function doesn't block and returns right away, after having attempted to open a connection to the CSMS.
// If the connection couldn't be opened, it retries.
//
// Optional client options must be set before calling this function. Refer to NewChargingStation.
StartWithRetries(csmsUrl string)
// Stops the charging station routine, disconnecting it from the CSMS.
// Any pending requests are discarded.
Stop()
Expand Down
11 changes: 11 additions & 0 deletions ocppj/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,17 @@ func (c *Client) Start(serverURL string) error {
return err
}

func (c *Client) StartWithRetries(serverURL string) {
// Set internal message handler
c.client.SetMessageHandler(c.ocppMessageHandler)
c.client.SetDisconnectedHandler(c.onDisconnected)
c.client.SetReconnectedHandler(c.onReconnected)
// Connect & run
fullUrl := fmt.Sprintf("%v/%v", serverURL, c.Id)
c.client.StartWithRetries(fullUrl)
c.dispatcher.Start()
}

// Stops the client.
// The underlying I/O loop is stopped and all pending requests are cleared.
func (c *Client) Stop() {
Expand Down
23 changes: 22 additions & 1 deletion ws/websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,17 @@ type WsClient interface {
//
// To stop a running client, call the Stop function.
Start(url string) error
// Starts the client and attempts to connect to the server on a specified URL.
// If the connection fails, it keeps retrying with Backoff strategy from TimeoutConfig.
//
// For example:
// client.StartWithRetries("ws://localhost:8887/ws/1234")
//
// The function returns only when the connection has been established.
// Incoming messages are passed automatically to the callback function, so no explicit read operation is required.
//
// To stop a running client, call the Stop function.
StartWithRetries(url string)
// Closes the output of the websocket Channel, effectively closing the connection to the server with a normal closure.
Stop()
// Errors returns a channel for error messages. If it doesn't exist it es created.
Expand Down Expand Up @@ -997,6 +1008,7 @@ func (client *Client) handleReconnection() {
return
}

log.Info("reconnecting... attempt", reconnectionAttempts)
err := client.Start(client.url.String())
if err == nil {
// Re-connection was successful
Expand Down Expand Up @@ -1038,8 +1050,17 @@ func (client *Client) Write(data []byte) error {
return nil
}

func (client *Client) StartWithRetries(urlStr string) {
err := client.Start(urlStr)
if err != nil {
log.Info("Connection error:", err)
client.handleReconnection()
}
}

func (client *Client) Start(urlStr string) error {
url, err := url.Parse(urlStr)
client.url = *url
if err != nil {
return err
}
Expand Down Expand Up @@ -1072,7 +1093,7 @@ func (client *Client) Start(urlStr string) error {

// The id of the charge point is the final path element
id := path.Base(url.Path)
client.url = *url

client.webSocket = WebSocket{
connection: ws,
id: id,
Expand Down
39 changes: 39 additions & 0 deletions ws/websocket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,45 @@ func TestWebsocketEcho(t *testing.T) {
wsServer.Stop()
}

func TestWebsocketBootRetries(t *testing.T) {
verifyConnection := func(client *Client, connected bool) {
maxAttempts := 20
for i := 0; i <= maxAttempts; i++ {
if client.IsConnected() != connected {
time.Sleep(time.Duration(2) * time.Second)
continue
}
}
assert.Equal(t, connected, client.IsConnected())
}
wsServer := newWebsocketServer(t, func(data []byte) ([]byte, error) {
return data, nil
})
wsClient := newWebsocketClient(t, func(data []byte) ([]byte, error) {
return nil, nil
})

go func() {
// Start websocket client
host := fmt.Sprintf("localhost:%v", serverPort)
u := url.URL{Scheme: "ws", Host: host, Path: testPath}
wsClient.StartWithRetries(u.String())
}()

assert.Equal(t, wsClient.IsConnected(), false)

time.Sleep(time.Duration(3) * time.Second)

go wsServer.Start(serverPort, serverPath)
verifyConnection(wsClient, true)

wsServer.Stop()
verifyConnection(wsClient, false)

wsServer.Stop()
wsClient.Stop()
}

func TestTLSWebsocketEcho(t *testing.T) {
message := []byte("Hello Secure WebSocket!")
triggerC := make(chan bool, 1)
Expand Down

0 comments on commit 884877e

Please sign in to comment.