Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,18 +389,27 @@ own logging system.

### Websocket ping-pong

The websocket package currently supports client-initiated pings only.
The websocket package supports configuring ping pong for both endpoints.

If your setup requires the server to be the initiator of a ping-pong (e.g. for web-based charge points),
you may disable ping-pong entirely and just rely on the heartbeat mechanism:
By default, the client sends a ping every 54 seconds and waits for a pong for 60 seconds, before timing out.
The values can be configured as follows:
```go
cfg := ws.NewClientTimeoutConfig()
cfg.PingPeriod = 10 * time.Second
cfg.PongWait = 20 * time.Second
websocketClient.SetTimeoutConfig(cfg)
```

By default, the server does not send out any pings and waits for a ping from the client for 60 seconds, before timing out.
To configure the server to send out pings, the `PingPeriod` and `PongWait` must be set to a value greater than 0:
```go
cfg := ws.NewServerTimeoutConfig()
cfg.PingWait = 0 // this instructs the server to wait forever
cfg.PingPeriod = 10 * time.Second
cfg.PongWait = 20 * time.Second
websocketServer.SetTimeoutConfig(cfg)
```

> A server-initiated ping may be supported in a future release.
To disable sending ping messages, set the `PingPeriod` value to `0`.

## OCPP 2.0.1 Usage

Expand Down
4 changes: 2 additions & 2 deletions example/1.6/cp/charge_point_sim.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ func setupTlsChargePoint(chargePointID string) ocpp16.ChargePoint {
}
}
// Create client with TLS config
client := ws.NewTLSClient(&tls.Config{
client := ws.NewClient(ws.WithClientTLSConfig(&tls.Config{
RootCAs: certPool,
Certificates: clientCertificates,
})
}))
return ocpp16.NewChargePoint(chargePointID, nil, client)
}

Expand Down
4 changes: 2 additions & 2 deletions example/1.6/cs/central_system_sim.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ func setupTlsCentralSystem() ocpp16.CentralSystem {
if !ok {
log.Fatalf("no required %v found", envVarServerCertificateKey)
}
server := ws.NewTLSServer(certificate, key, &tls.Config{
server := ws.NewServer(ws.WithServerTLSConfig(certificate, key, &tls.Config{
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: certPool,
})
}))
return ocpp16.NewCentralSystem(nil, server)
}

Expand Down
4 changes: 2 additions & 2 deletions example/2.0.1/chargingstation/charging_station_sim.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ func setupTlsChargingStation(chargingStationID string) ocpp2.ChargingStation {
}
}
// Create client with TLS config
client := ws.NewTLSClient(&tls.Config{
client := ws.NewClient(ws.WithClientTLSConfig(&tls.Config{
RootCAs: certPool,
Certificates: clientCertificates,
})
}))
return ocpp2.NewChargingStation(chargingStationID, nil, client)
}

Expand Down
4 changes: 2 additions & 2 deletions example/2.0.1/csms/csms_sim.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ func setupTlsCentralSystem() ocpp2.CSMS {
if !ok {
log.Fatalf("no required %v found", envVarServerCertificateKey)
}
server := ws.NewTLSServer(certificate, key, &tls.Config{
server := ws.NewServer(ws.WithServerTLSConfig(certificate, key, &tls.Config{
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: certPool,
})
}))
return ocpp2.NewCSMS(nil, server)
}

Expand Down
12 changes: 6 additions & 6 deletions ocpp1.6/v16.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,13 @@ type ChargePoint interface {
// if !ok {
// log.Fatal("couldn't parse PEM certificate")
// }
// cp := NewClient("someUniqueId", nil, ws.NewTLSClient(&tls.Config{
// cp := NewClient("someUniqueId", nil, ws.NewClient(ws.WithClientTLSConfig(&tls.Config{
// RootCAs: certPool,
// })
// }))
//
// For more advanced options, or if a customer networking/occpj layer is required,
// please refer to ocppj.Client and ws.WsClient.
func NewChargePoint(id string, endpoint *ocppj.Client, client ws.WsClient) ChargePoint {
// please refer to ocppj.Client and ws.Client.
func NewChargePoint(id string, endpoint *ocppj.Client, client ws.Client) ChargePoint {
if client == nil {
client = ws.NewClient()
}
Expand Down Expand Up @@ -338,8 +338,8 @@ type CentralSystem interface {
//
// If you need a TLS server, you may use the following:
//
// cs := NewServer(nil, ws.NewTLSServer("certificatePath", "privateKeyPath"))
func NewCentralSystem(endpoint *ocppj.Server, server ws.WsServer) CentralSystem {
// cs := NewServer(nil, ws.NewServer(ws.WithServerTLSConfig("certificatePath", "privateKeyPath", nil)))
func NewCentralSystem(endpoint *ocppj.Server, server ws.Server) CentralSystem {
if server == nil {
server = ws.NewServer()
}
Expand Down
50 changes: 9 additions & 41 deletions ocpp1.6_test/ocpp16_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"crypto/tls"
"fmt"
"net"
"net/http"
"reflect"
"testing"
"time"
Expand Down Expand Up @@ -50,14 +49,18 @@ func (websocket MockWebSocket) TLSConnectionState() *tls.ConnectionState {
return nil
}

func (websocket MockWebSocket) IsConnected() bool {
return true
}

func NewMockWebSocket(id string) MockWebSocket {
return MockWebSocket{id: id}
}

// ---------------------- MOCK WEBSOCKET SERVER ----------------------
type MockWebsocketServer struct {
mock.Mock
ws.WsServer
ws.Server
MessageHandler func(ws ws.Channel, data []byte) error
NewClientHandler func(ws ws.Channel)
CheckClientHandler ws.CheckClientHandler
Expand All @@ -77,11 +80,11 @@ func (websocketServer *MockWebsocketServer) Write(webSocketId string, data []byt
return args.Error(0)
}

func (websocketServer *MockWebsocketServer) SetMessageHandler(handler func(ws ws.Channel, data []byte) error) {
func (websocketServer *MockWebsocketServer) SetMessageHandler(handler ws.MessageHandler) {
websocketServer.MessageHandler = handler
}

func (websocketServer *MockWebsocketServer) SetNewClientHandler(handler func(ws ws.Channel)) {
func (websocketServer *MockWebsocketServer) SetNewClientHandler(handler ws.ConnectedHandler) {
websocketServer.NewClientHandler = handler
}

Expand All @@ -96,14 +99,14 @@ func (websocketServer *MockWebsocketServer) NewClient(websocketId string, client
websocketServer.MethodCalled("NewClient", websocketId, client)
}

func (websocketServer *MockWebsocketServer) SetCheckClientHandler(handler func(id string, r *http.Request) bool) {
func (websocketServer *MockWebsocketServer) SetCheckClientHandler(handler ws.CheckClientHandler) {
websocketServer.CheckClientHandler = handler
}

// ---------------------- MOCK WEBSOCKET CLIENT ----------------------
type MockWebsocketClient struct {
mock.Mock
ws.WsClient
ws.Client
MessageHandler func(data []byte) error
ReconnectedHandler func()
DisconnectedHandler func(err error)
Expand Down Expand Up @@ -445,41 +448,6 @@ func (smartChargingListener *MockChargePointSmartChargingListener) OnGetComposit
}

// ---------------------- COMMON UTILITY METHODS ----------------------
func NewWebsocketServer(t *testing.T, onMessage func(data []byte) ([]byte, error)) *ws.Server {
wsServer := ws.Server{}
wsServer.SetMessageHandler(func(ws ws.Channel, data []byte) error {
assert.NotNil(t, ws)
assert.NotNil(t, data)
if onMessage != nil {
response, err := onMessage(data)
assert.Nil(t, err)
if response != nil {
err = wsServer.Write(ws.ID(), data)
assert.Nil(t, err)
}
}
return nil
})
return &wsServer
}

func NewWebsocketClient(t *testing.T, onMessage func(data []byte) ([]byte, error)) *ws.Client {
wsClient := ws.Client{}
wsClient.SetMessageHandler(func(data []byte) error {
assert.NotNil(t, data)
if onMessage != nil {
response, err := onMessage(data)
assert.Nil(t, err)
if response != nil {
err = wsClient.Write(data)
assert.Nil(t, err)
}
}
return nil
})
return &wsClient
}

type expectedCentralSystemOptions struct {
clientId string
rawWrittenMessage []byte
Expand Down
12 changes: 6 additions & 6 deletions ocpp2.0.1/v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,13 +202,13 @@ type ChargingStation interface {
// if !ok {
// log.Fatal("couldn't parse PEM certificate")
// }
// cs := NewChargingStation("someUniqueId", nil, ws.NewTLSClient(&tls.Config{
// cs := NewChargingStation("someUniqueId", nil, ws.NewClient(ws.WithClientTLSConfig(&tls.Config{
// RootCAs: certPool,
// })
// }))
//
// For more advanced options, or if a custom networking/occpj layer is required,
// please refer to ocppj.Client and ws.WsClient.
func NewChargingStation(id string, endpoint *ocppj.Client, client ws.WsClient) ChargingStation {
// please refer to ocppj.Client and ws.Client.
func NewChargingStation(id string, endpoint *ocppj.Client, client ws.Client) ChargingStation {
if client == nil {
client = ws.NewClient()
}
Expand Down Expand Up @@ -414,8 +414,8 @@ type CSMS interface {
//
// If you need a TLS server, you may use the following:
//
// csms := NewCSMS(nil, ws.NewTLSServer("certificatePath", "privateKeyPath"))
func NewCSMS(endpoint *ocppj.Server, server ws.WsServer) CSMS {
// csms := NewCSMS(nil, ws.NewServer(ws.WithServerTLSConfig("certificatePath", "privateKeyPath", nil)))
func NewCSMS(endpoint *ocppj.Server, server ws.Server) CSMS {
if server == nil {
server = ws.NewServer()
}
Expand Down
51 changes: 9 additions & 42 deletions ocpp2.0.1_test/ocpp2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"crypto/tls"
"fmt"
"net"
"net/http"
"reflect"
"testing"
"time"
Expand Down Expand Up @@ -59,6 +58,10 @@ func (websocket MockWebSocket) TLSConnectionState() *tls.ConnectionState {
return nil
}

func (websocket MockWebSocket) IsConnected() bool {
return true
}

func NewMockWebSocket(id string) MockWebSocket {
return MockWebSocket{id: id}
}
Expand All @@ -67,7 +70,7 @@ func NewMockWebSocket(id string) MockWebSocket {

type MockWebsocketServer struct {
mock.Mock
ws.WsServer
ws.Server
MessageHandler func(ws ws.Channel, data []byte) error
NewClientHandler func(ws ws.Channel)
CheckClientHandler ws.CheckClientHandler
Expand All @@ -87,11 +90,11 @@ func (websocketServer *MockWebsocketServer) Write(webSocketId string, data []byt
return args.Error(0)
}

func (websocketServer *MockWebsocketServer) SetMessageHandler(handler func(ws ws.Channel, data []byte) error) {
func (websocketServer *MockWebsocketServer) SetMessageHandler(handler ws.MessageHandler) {
websocketServer.MessageHandler = handler
}

func (websocketServer *MockWebsocketServer) SetNewClientHandler(handler func(ws ws.Channel)) {
func (websocketServer *MockWebsocketServer) SetNewClientHandler(handler ws.ConnectedHandler) {
websocketServer.NewClientHandler = handler
}

Expand All @@ -106,15 +109,15 @@ func (websocketServer *MockWebsocketServer) NewClient(websocketId string, client
websocketServer.MethodCalled("NewClient", websocketId, client)
}

func (websocketServer *MockWebsocketServer) SetCheckClientHandler(handler func(id string, r *http.Request) bool) {
func (websocketServer *MockWebsocketServer) SetCheckClientHandler(handler ws.CheckClientHandler) {
websocketServer.CheckClientHandler = handler
}

// ---------------------- MOCK WEBSOCKET CLIENT ----------------------

type MockWebsocketClient struct {
mock.Mock
ws.WsClient
ws.Client
MessageHandler func(data []byte) error
ReconnectedHandler func()
DisconnectedHandler func(err error)
Expand Down Expand Up @@ -812,42 +815,6 @@ func (handler *MockCSMSTransactionsHandler) OnTransactionEvent(chargingStationID
}

// ---------------------- COMMON UTILITY METHODS ----------------------

func NewWebsocketServer(t *testing.T, onMessage func(data []byte) ([]byte, error)) *ws.Server {
wsServer := ws.Server{}
wsServer.SetMessageHandler(func(ws ws.Channel, data []byte) error {
assert.NotNil(t, ws)
assert.NotNil(t, data)
if onMessage != nil {
response, err := onMessage(data)
assert.Nil(t, err)
if response != nil {
err = wsServer.Write(ws.ID(), data)
assert.Nil(t, err)
}
}
return nil
})
return &wsServer
}

func NewWebsocketClient(t *testing.T, onMessage func(data []byte) ([]byte, error)) *ws.Client {
wsClient := ws.Client{}
wsClient.SetMessageHandler(func(data []byte) error {
assert.NotNil(t, data)
if onMessage != nil {
response, err := onMessage(data)
assert.Nil(t, err)
if response != nil {
err = wsClient.Write(data)
assert.Nil(t, err)
}
}
return nil
})
return &wsClient
}

type expectedCSMSOptions struct {
clientId string
rawWrittenMessage []byte
Expand Down
2 changes: 1 addition & 1 deletion ocppj/central_system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ func (suite *OcppJTestSuite) TestCentralSystemNewClientHandler() {
suite.mockServer.NewClientHandler(channel)
ok := <-connectedC
assert.True(t, ok)
// Client state was created
// client state was created
_, ok = suite.serverRequestMap.Get(mockClientID)
assert.True(t, ok)
}
Expand Down
4 changes: 2 additions & 2 deletions ocppj/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
// During message exchange, the two roles may be reversed (depending on the message direction), but a client struct remains associated to a charge point/charging station.
type Client struct {
Endpoint
client ws.WsClient
client ws.Client
Id string
requestHandler func(request ocpp.Request, requestId string, action string)
responseHandler func(response ocpp.Response, requestId string)
Expand All @@ -35,7 +35,7 @@ type Client struct {
//
// The wsClient parameter cannot be nil. Refer to the ws package for information on how to create and
// customize a websocket client.
func NewClient(id string, wsClient ws.WsClient, dispatcher ClientDispatcher, stateHandler ClientState, profiles ...*ocpp.Profile) *Client {
func NewClient(id string, wsClient ws.Client, dispatcher ClientDispatcher, stateHandler ClientState, profiles ...*ocpp.Profile) *Client {
endpoint := Endpoint{}
if wsClient == nil {
panic("wsClient parameter cannot be nil")
Expand Down
Loading