DEV Community

HarmonyOS
HarmonyOS

Posted on

How to Use WebSocket Properly in HarmonyOS

Read the original article:How to Use WebSocket Properly in HarmonyOS

Context

You need a concise, paste-ready guide for implementing and testing WebSockets in a HarmonyOS app using @kit.NetworkKit, including permissions, a reusable service, UI wiring, and sample logs.

Description

WebSockets provide full-duplex, long-lived connections over a single TCP link. This document shows how to configure permissions, build a WebSocketManager service, connect/send/receive, and handle lifecycle events (open, message, close, error). It also includes a quick UI hook-up and example console outputs.

Solution / Approach

1) Required permission (module.json5)

"requestPermissions": [
  {
    "name": "ohos.permission.INTERNET",
    "reason": "$string:net_reason",
    "usedScene": { "when": "inuse" }
  }
]
Enter fullscreen mode Exit fullscreen mode

2) String resource (string.json)

{
  "name": "net_reason",
  "value": "This app needs Internet Permission"
}

Enter fullscreen mode Exit fullscreen mode

3) Reusable service (WebSocketManager.ets)

import { webSocket } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';

@ObservedV2
class WebSocketManager {
  private socket = webSocket.createWebSocket();
  private defaultUrl: string = 'wss://ws.postman-echo.com/raw';

  @Trace isConnected: boolean = false;
  @Trace text: string = 'Tap to test WebSocket';

  setupWebSocket(): void {
    this.socket.on('open', (err: BusinessError, value: Object) => {
      console.log('on open:', JSON.stringify(value ?? {}));
      this.isConnected = true;
      this.text = 'Connected. Sending message...';
      this.socket.send('Hello from HarmonyOS!', (sendErr: BusinessError, ok: boolean) => {
        if (!sendErr && ok) {
          console.log('Message sent successfully');
          this.text = 'Message sent successfully';
        } else {
          console.log('Failed to send message:', JSON.stringify(sendErr));
          this.text = 'Failed to send message';
        }
      });
    });

    this.socket.on('message', (err: BusinessError, value: string | ArrayBuffer) => {
      console.log('on message:', value);
      this.text = 'Message received: ' + value;
      if (value === 'Hello from HarmonyOS!') {
        this.socket.close((closeErr: BusinessError, ok: boolean) => {
          if (!closeErr && ok) {
            console.log('Connection closed successfully');
          } else {
            console.log('Failed to close connection:', JSON.stringify(closeErr));
          }
        });
      }
    });

    this.socket.on('close', (err: BusinessError, value: webSocket.CloseResult) => {
      console.log(`on close: code=${value.code}, reason=${value.reason}`);
      this.isConnected = false;
      this.text = 'Socket closed';
    });

    this.socket.on('error', (err: BusinessError) => {
      console.log('on error:', JSON.stringify(err));
      this.text = 'Socket error';
    });

    this.socket.connect(this.defaultUrl, (connErr: BusinessError, ok: boolean) => {
      if (!connErr && ok) {
        console.log('Connected to Postman Echo');
      } else {
        console.log('Connection failed:', JSON.stringify(connErr));
      }
    });
  }

  connectLiveSocket(url: string): void {
    if (this.isConnected) {
      console.log('WebSocket already connected');
      return;
    }
    this.socket.connect(url, (err: BusinessError, ok: boolean) => {
      if (!err && ok) {
        console.log('Connected to WebSocket server');
      } else {
        console.log('Connection failed:', JSON.stringify(err));
      }
    });
  }

  disconnectLiveSocket(): void {
    if (!this.isConnected) {
      console.log('WebSocket is not connected');
      return;
    }
    this.socket.close((err: BusinessError, ok: boolean) => {
      if (!err && ok) {
        console.log('WebSocket disconnected successfully');
      } else {
        console.log('Disconnection failed:', JSON.stringify(err));
      }
    });
  }

  sendMessage(message: string): void {
    if (!this.isConnected) {
      console.log('Cannot send — WebSocket not connected');
      return;
    }
    this.socket.send(message, (err: BusinessError, ok: boolean) => {
      if (!err && ok) {
        console.log('Message sent:', message);
      } else {
        console.log('Send failed:', JSON.stringify(err));
      }
    });
  }
}

export const webSocketManager = new WebSocketManager();
Enter fullscreen mode Exit fullscreen mode

4) Example UI usage

// e.g., inside a Button
.onClick(() => {
  webSocketManager.setupWebSocket();
})

// Bind this somewhere in your UI to observe status
// Text(webSocketManager.text)
Enter fullscreen mode Exit fullscreen mode

5) Example console outputs

  • On open on open: {} Connected to Postman Echo Message sent successfully
  • On message on message: Hello from HarmonyOS! Connection closed successfully
  • On error on error: {...}

Tips

  • Prefer wss:// in production; some test endpoints may reject insecure ws://.
  • If using a self-signed cert in dev, ensure your device trusts it or use a known echo server.
  • Update isConnected in open/close to keep UI logic accurate (already shown above).

Key Takeaways

  • Add and justify INTERNET permission before using WebSockets.
  • Centralize socket logic in a reusable WebSocketManager to simplify UI.
  • Always handle all lifecycle events: open, message, close, error.
  • Reflect connection state in UI and guard sendMessage/disconnect calls.

Written by Sinan Yilmaz

Top comments (0)