什么是 WebSocket Client?WebSocket Client 的类型和使用

WebSocket clients 是现代 Web 应用程序的重要组件,可实现客户端与服务器之间的实时通信。通过了解 WebSocket 协议,开发人员可以创建强大的应用程序,充分利用这一强大的技术。

本文面向初学者,介绍了一些最流行的客户端语言的 WebSocket client 实现,并解释了适用于所有实现的标准 WebSocket API 事件。

什么是 WebSocket Client ?

WebSocket client 与 WebSocket 服务器建立连接;该连接是一个双向、全双工的通信通道,允许客户端和服务器同时进行双向数据交换。WebSocket 客户端可以用所有流行的编程语言实现,如 JavaScript、Python、Swift 等。

WebSocket client 通常使用 WebSocket 协议 (WSS) 与 WebSocket 服务器交互。该协议设计为在 TCP 上通过与 HTTP 和 HTTPS 相同的端口(分别为 80 端口和 443 端口)工作,并使用 WebSocket 握手建立连接。一旦建立连接,WebSocket 客户端就可以通过 onmessage 事件处理程序/回调来发送和接收信息。

WebSocket 指的是这项技术本身,而 WebSocket client 则是这项技术在应用程序中的实现。WebSocket client 负责初始化连接、处理接收到的信息以及管理连接的生命周期(onopen、onmessage、onerror 和 onclose 事件)。WebSockets 不同于 HTTP,因此您连接的不是 HTTP 服务器,而是 WebSocket 服务器,而不是向 HTTP 服务器发出 HTTP 请求。

如何使用 WebSocket clients

有效使用 WebSocket 客户端需要了解其生命周期事件并加以处理。

初始化 WebSocket client

要初始化 WebSocket clients,需要创建一个新的 WebSocket 对象,并将所需的端点(URI)作为参数。端点应是您要连接的 WebSocket 服务器的地址。例如,在 JavaScript 中

const websocket = new WebSocket("ws://my-socket-server:80");

处理 WebSocket 事件

WebSocket 规范中定义了四个与客户端相关的主要事件:onopen、onmessage、onerror 和 onclose。您应该定义事件处理程序来管理 Web 应用程序中的这些事件。 

  • onopen:WebSocket 连接成功建立时触发该事件。您可以使用此事件开始向服务器发送消息、初始化应用程序或执行需要活动连接的其他任务。这通常在应用程序的构造函数中声明
  • onmessage(msg):当从 WebSocket 服务器接收到消息时,会触发此事件。消息事件包含服务器发送的有效负载(event.data)。您可以使用此事件来处理传入数据、更新应用程序的状态或根据接收到的数据执行其他任务。
  • onerror:WebSocket 连接过程中发生错误时触发该事件。您可以使用此事件来处理错误、向用户显示错误消息或执行与错误处理相关的其他任务。
  • onclose:关闭 WebSocket 连接时触发此关闭事件。您可以使用此事件来清理资源、通知用户断开连接或在必要时尝试重新连接。

其他参数也可用,例如子协议、身份验证和发送二进制数据,但上述事件足以开始。WebSocket 不允许您指定任何自定义标头。

关闭 WebSocket 连接

要关闭 WebSocket 连接,只需调用 WebSocket 对象上的 close() 方法即可:

websocket.close();

这将触发 onclose 事件,使您可以执行任何必要的清理任务。

WebSocket clients 类型

所有主要语言都有 WebSocket 实现,或者作为语言本身的一部分,或者由标准软件包或流行软件包提供。下面的代码示例给出了 WebSocket 客户端在不同编程语言中的典型实现,并酌情提供了依赖关系。

Python WebSocket client

要在 Python 中创建 WebSocket client,可以如下使用 WebSocket 库:

import websocket

def on_message(ws, message):
    print("Received message:", message)

def on_error(ws, error):
    print("Error:", error)

def on_close(ws):
    print("Connection closed")

def on_open(ws):
    ws.send("Hello, websocket server!")

if __name__ == "__main__":
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp("ws://localhost:8080",
                                 on_message=on_message,
                                 on_error=on_error,
                                 on_close=on_close)
    ws.on_open = on_open
    ws.run_forever()

C# WebSocket client

C# 通过属于 System.NET.WebSockets 命名空间的 ClientWebSocket 类提供了 WebSocket 客户端。

下面的代码将连接到位于 wss://my-websocket-server.com 的 WebSocket 服务器。建立连接后,它将监听消息,在控制台上显示这些消息,并向服务器发送回复。

using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace WebSocketClientExample
{
    class Program
    {
        private static async Task Main(string[] args)
        {
            Uri serverUri = new Uri("wss://my-websocket-server.com");
            await ConnectWebSocketAsync(serverUri);
            Console.ReadKey();
        }

        private static async Task ConnectWebSocketAsync(Uri serverUri)
        {
            using (ClientWebSocket webSocket = new ClientWebSocket())
            {
                await webSocket.ConnectAsync(serverUri, CancellationToken.None);
                Console.WriteLine("WebSocket connection opened");

                _ = Task.Run(async () =>
                {
                    while (webSocket.State == WebSocketState.Open)
                    {
                        WebSocketReceiveResult result;
                        ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024]);
                        do
                        {
                            result = await webSocket.ReceiveAsync(buffer, CancellationToken.None);
                            string message = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);
                            Console.WriteLine("Received message: " + message);
                        }
                        while (!result.EndOfMessage);
                    }
                });

                // Send a message to the WebSocket server
                string sendMessage = "Hello, WebSocket Server!";
                ArraySegment<byte> sendBuffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(sendMessage));
                await webSocket.SendAsync(sendBuffer, WebSocketMessageType.Text, true, CancellationToken.None);
                Console.WriteLine("Sent message: " + sendMessage);
            }
        }
    }
}

JavaScript WebSocket client

JavaScript 是一种广泛采用的客户端 Web 开发语言。使用 JavaScript / HTML 创建 WebSocket client非常简单,因为该语言本身支持 WebSocket API。

const websocket = new WebSocket("wss://my-websocket-server.com");

websocket.onopen = function(event) {
  console.log("Connected!");
  websocket.send("Hello, WebSocket server!");
};

websocket.onmessage = function(event) {
  console.log("Received message:", event.data);
};

websocket.onerror = function(event) {
  console.log("Error:", event);
};

websocket.onclose = function(event) {
  console.log("Connection closed");
};

Node.js WebSocket client

Node.js 是一种流行的运行时环境,用于在服务器端执行 JavaScript。要在 Node.js 中创建 WebSocket client,您可以使用“ws”库。

const WebSocket = require('ws');
const websocket = new WebSocket('wss://my-websocket-server.com');

websocket.on('open', function open() {
  console.log('Connected!');
  websocket.send('Hello, WebSocket server!');
});

websocket.on('message', function incoming(message) {
  console.log('Received message:', message);
});

websocket.on('error', function error(err) {
  console.log('Error:', err);
});

websocket.on('close', function close() {
  console.log('Connection closed');
});

React WebSocket client

本示例在 React 中创建了一个简单的 WebSocket client 组件,当组件挂载时,它会连接到 WebSocket 服务器,监听消息并相应地更新状态。sendMessage 函数向 WebSocket 服务器发送消息。

import React, { useState, useEffect } from 'react';

const WebSocketClient = () => {
  const [messages, setMessages] = useState([]);
  const [ws, setWs] = useState(null);

  useEffect(() => {
    const websocket = new WebSocket('wss://my-websocket-server.com');
    
    websocket.onopen = () => {
      console.log('WebSocket connection opened');
    };

    websocket.onmessage = (event) => {
      const newMessage = event.data;
      setMessages((prevMessages) => [...prevMessages, newMessage]);
    };

    websocket.onclose = () => {
      console.log('WebSocket connection closed');
    };

    websocket.onerror = (error) => {
      console.error('WebSocket error:', error);
    };

    setWs(websocket);

    return () => {
      websocket.close();
    };
  }, []);

  const sendMessage = (message) => {
    if (ws) {
      ws.send(message);
    }
  };

  return (
    <div id='myDiv'>
      <h2>WebSocket Client</h2>
      <ul>
        {messages.map((message, index) => (
          <li key={index}>{message}</li>
        ))}
      </ul>
      <button onClick={() => sendMessage('Hello, WebSocket Server!')}>
        Send Message
      </button>
    </div>
  );
};

export default WebSocketClient;

Swift WebSocket client

下面的代码使用 URLSessionWebSocketTask API 来建立 WebSocket 连接、监听消息并将其打印到控制台。sendMessage 函数将向 WebSocket 服务器发送消息,并在 5 秒延迟后断开连接。

import Foundation

class WebSocketClient {
    private let url: URL
    private var webSocketTask: URLSessionWebSocketTask?

    init(url: URL) {
        self.url = url
    }

    func connect() {
        let session = URLSession(configuration: .default)
        webSocketTask = session.webSocketTask(with: url)
        webSocketTask?.resume()
        receiveMessage()
    }

    func disconnect() {
        webSocketTask?.cancel(with: .goingAway, reason: nil)
    }

    private func receiveMessage() {
        webSocketTask?.receive { [weak self] result in
            switch result {
            case .success(let message):
                switch message {
                case .string(let text):
                    print("Received message: \(text)")
                case .data(let data):
                    print("Received data: \(data)")
                @unknown default:
                    print("Unknown message")
                }
                self?.receiveMessage()
            case .failure(let error):
                print("Error receiving message: \(error)")
            }
        }
    }

    func sendMessage(_ message: String) {
        webSocketTask?.send(.string(message)) { error in
            if let error = error {
                print("Error sending message: \(error)")
            } else {
                print("Sent message: \(message)")
            }
        }
    }
}

let serverUrl = URL(string: "wss://my-websocket-server.com")!
let webSocketClient = WebSocketClient(url: serverUrl)
webSocketClient.connect()

// Send a message to the WebSocket server
webSocketClient.sendMessage("Hello, WebSocket Server!")

// Disconnect after a delay
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
    webSocketClient.disconnect()
}

Golang WebSocket client

这个用 Go 编写的简单 WebSocket client 示例使用了流行的 github.com/gorilla/websocket 软件包。它建立一个 WebSocket 连接,监听消息并将消息打印到控制台。客户端每秒向 WebSocket 服务器发送一条消息,收到中断信号(如 Ctrl+C)后关闭连接。

package main

import (
	"fmt"
	"log"
	"net/url"
	"os"
	"os/signal"
	"time"

	"github.com/gorilla/websocket"
)

var interrupt chan os.Signal

func main() {
	interrupt = make(chan os.Signal, 1)
	signal.Notify(interrupt, os.Interrupt)

	u := url.URL{Scheme: "ws", Host: "my-websocket-server.com", Path: "/"}
	fmt.Printf("Connecting to %s\n", u.String())

	c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
	if err != nil {
		log.Fatal("dial:", err)
	}
	defer c.Close()

	done := make(chan struct{})

	go func() {
		defer close(done)
		for {
			_, message, err := c.ReadMessage()
			if err != nil {
				log.Println("Error during reading message:", err)
				return
			}
			fmt.Printf("Received: %s\n", message)
		}
	}()

	ticker := time.NewTicker(time.Second)
	defer ticker.Stop()

	for {
		select {
		case <-done:
			return
		case t := <-ticker.C:
			err := c.WriteMessage(websocket.TextMessage, []byte(t.String()))
			if err != nil {
				log.Println("Error during writing message:", err)
				return
			}
			fmt.Printf("Sent: %s\n", t.String())
		case <-interrupt:
			log.Println("Interrupt received, closing connection")
			err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
			if err != nil {
				log.Println("Error during closing connection:", err)
				return
			}
			select {
			case <-done:
			case <-time.After(time.Second):
			}
			return
		}
	}
}

使用 WebSocket clients 构建实时应用程序

通过利用 WebSocket clients,开发人员可以创建功能强大、反应灵敏的应用程序,以满足现代用户的需求。实时应用的范围包括聊天应用、在线游戏、实时数据流和协作平台。

以下是使用 WebSocket clients 构建实时应用程序时应遵循的一些步骤:

  • 选择正确的编程语言: 根据应用程序的要求和个人偏好,选择支持 WebSocket clients 的编程语言。如前所述,常用的语言包括 JavaScript、Python 和 React。
  • 实现 WebSocket 服务器: 除了 WebSocket client,您还需要一个 WebSocket 服务器来管理传入连接和处理数据交换。该服务器可以使用与 WebSocket 客户端相同的语言实现,也可以使用不同的语言,具体取决于您的需求。
  • 设计应用程序的架构: 仔细规划应用程序的结构,包括定义消息格式(如 JSON)、建立连接管理策略(如断开连接后重新连接)以及设计用户界面 (UI) 以处理实时更新。
  • 处理 WebSocket 事件: 如前所述,处理 WebSocket 事件(如 onopen、onmessage、onerror 和 onclose)对于管理 WebSocket 连接的生命周期至关重要。在应用程序中实施所需的事件处理程序,以交换信息和处理错误。

本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/41290.html

(0)

相关推荐

发表回复

登录后才能评论