github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/edge/pkg/edgehub/clients/wsclient/websocket.go (about)

     1  package wsclient
     2  
     3  import (
     4  	"crypto/tls"
     5  	"errors"
     6  	"fmt"
     7  	"net/http"
     8  	"time"
     9  
    10  	"k8s.io/klog"
    11  
    12  	"github.com/kubeedge/beehive/pkg/core/model"
    13  	"github.com/kubeedge/viaduct/pkg/api"
    14  	wsclient "github.com/kubeedge/viaduct/pkg/client"
    15  	"github.com/kubeedge/viaduct/pkg/conn"
    16  )
    17  
    18  const (
    19  	retryCount       = 5
    20  	cloudAccessSleep = 5 * time.Second
    21  )
    22  
    23  // WebSocketClient a websocket client
    24  type WebSocketClient struct {
    25  	config     *WebSocketConfig
    26  	connection conn.Connection
    27  }
    28  
    29  // WebSocketConfig config for websocket
    30  type WebSocketConfig struct {
    31  	URL              string
    32  	CertFilePath     string
    33  	KeyFilePath      string
    34  	HandshakeTimeout time.Duration
    35  	ReadDeadline     time.Duration
    36  	WriteDeadline    time.Duration
    37  	NodeID           string
    38  	ProjectID        string
    39  }
    40  
    41  // NewWebSocketClient initializes a new websocket client instance
    42  func NewWebSocketClient(conf *WebSocketConfig) *WebSocketClient {
    43  	return &WebSocketClient{config: conf}
    44  }
    45  
    46  // Init initializes websocket client
    47  func (wsc *WebSocketClient) Init() error {
    48  	klog.Infof("Websocket start to connect Access")
    49  	cert, err := tls.LoadX509KeyPair(wsc.config.CertFilePath, wsc.config.KeyFilePath)
    50  	if err != nil {
    51  		klog.Errorf("Failed to load x509 key pair: %v", err)
    52  		return fmt.Errorf("failed to load x509 key pair, error: %v", err)
    53  	}
    54  
    55  	tlsConfig := &tls.Config{
    56  		Certificates:       []tls.Certificate{cert},
    57  		InsecureSkipVerify: true,
    58  	}
    59  
    60  	option := wsclient.Options{
    61  		HandshakeTimeout: wsc.config.HandshakeTimeout,
    62  		TLSConfig:        tlsConfig,
    63  		Type:             api.ProtocolTypeWS,
    64  		Addr:             wsc.config.URL,
    65  		AutoRoute:        false,
    66  		ConnUse:          api.UseTypeMessage,
    67  	}
    68  	exOpts := api.WSClientOption{Header: make(http.Header)}
    69  	exOpts.Header.Set("node_id", wsc.config.NodeID)
    70  	exOpts.Header.Set("project_id", wsc.config.ProjectID)
    71  	client := &wsclient.Client{Options: option, ExOpts: exOpts}
    72  
    73  	for i := 0; i < retryCount; i++ {
    74  		connection, err := client.Connect()
    75  		if err != nil {
    76  			klog.Errorf("Init websocket connection failed %s", err.Error())
    77  		} else {
    78  			wsc.connection = connection
    79  			klog.Infof("Websocket connect to cloud access successful")
    80  			return nil
    81  		}
    82  		time.Sleep(cloudAccessSleep)
    83  	}
    84  	return errors.New("max retry count reached when connecting to cloud")
    85  }
    86  
    87  //Uninit closes the websocket connection
    88  func (wsc *WebSocketClient) Uninit() {
    89  	wsc.connection.Close()
    90  }
    91  
    92  //Send sends the message as JSON object through the connection
    93  func (wsc *WebSocketClient) Send(message model.Message) error {
    94  	return wsc.connection.WriteMessageAsync(&message)
    95  }
    96  
    97  //Receive reads the binary message through the connection
    98  func (wsc *WebSocketClient) Receive() (model.Message, error) {
    99  	message := model.Message{}
   100  	wsc.connection.ReadMessage(&message)
   101  	return message, nil
   102  }
   103  
   104  //Notify logs info
   105  func (wsc *WebSocketClient) Notify(authInfo map[string]string) {
   106  	klog.Infof("no op")
   107  }