Building a Robust Instant Messaging System on OpenHarmony

Implementation Overveiw

Instant messaging enables real-time exchange of text, multimedia, and documents between multiple devices. This implementation targets the OpenHarmony ecosystem, utilizing a client-server architecture deployed on hardware such as the DAYU200 RK3568 board running OpenHarmony 3.1.

Core Architecture

Successful inter-device communication relies on synchronized clients and a central relay server. Users must register credentials before establishing connections. Once authenticated, peers can discover each other and initiate sessions. Messages traverce the network to the server, which handles routing based on recipient availability—delivering instantly if online or queueing offline data until the next connection.

Key prerequisites include installed applications on both endpoints, valid user accounts, and an established contact list. The workflow involves composing payloads (text, images, audio), transmitting via TCP/IP to the backend, and rendering incoming data upon receipt.

Network Communication Layer

The underlying transport utilizes TCP sockets. Native C++ logic wraps the core networking functions and exposes them to the JavaScript runtime through Node-API (NAPI). This allows asynchronous network handling within the application framework.

// Initialize socket connection to the server
int socketFd = createClientSocket();
int connectionResult = connect(socketFd, reinterpret_cast<struct sockaddr*>(&serverAddr), sizeof(serverAddr));
napi_value response;

if (connectionResult < 0) {
    napi_create_int32(env, 0, &response);
} else {
    napi_create_int32(env, 1, &response);
    OH_LOG_INFO(APP_TAG, "Background receiver thread initialized");
    startReceptionThread();
}

// Transmit data packet
size_t bytesSent = send(socketFd, bufferData, dataLength, MSG_NOSIGNAL);
if (bytesSent == -1) {
    OH_LOG_WARN(APP_TAG, "Transmission failed: Socket write error");
    napi_create_int32(env, 0, &response);
} else {
    napi_create_int32(env, 1, &response);
}

// Retrieve incoming buffer
getIncomingQueue(receiveBuffer, sharedMessage);
const char* decodedStr = sharedMessage.c_str();
napi_value msgVal;
napi_create_string_utf8(env, decodedStr, sharedMessage.size(), &msgVal);
std::string().swap(sharedMessage);

Media Transfer Mechanism

Support for binary objects requires specific upload and download handlers managed by the HTTP request utility.

File Exchange

Users trigger file transfers via the interface action menu. The process selects a local path, uploads it to a cloud endpoint, and marks it available for retrieval.

// Construct upload payload with metadata
const currentFile = {
    key: `${userUid}-transfer-${timestamp}`,
    displayName: 'attachment',
    uri: selectedFilePath,
    type: mimeType
};
const fileId = generateUniqueId();

const uploadOptions = {
    url: `http://${baseServerIp}/upload`,
    method: 'POST',
    files: [currentFile],
    headers: { 'fileName': fileName }
};

request.upload(uploadOptions).then(task => {
    task.on('headerReceive', () => {
        notifyServerCompletion(fileId);
    });
}).catch(err => {
    console.error(`Upload aborted: ${err.message}`);
});

// Download configuration
const downloadParams = {
    sourceUrl: remoteResourceUrl,
    outputPath: `/data/storage/el2/files/${localFileName}`,
    networkPreference: 'wifi_only'
};

request.download(downloadParams, (error, task) => {
    if (error) return;
    task.on('complete', () => {
        showToast('File saved successfully');
    });
});

Voice Communications

Recording is handled by the system audio service. Files are processed similarly to documents, involving preparation, capture, upload, and playback.

// Setup audio recording session
initAudioRecorder(recordConfig, (status) => {
    if (status !== 'null') {
        recorder.start();
    }
});

const recordingPath = `cache://recordings/audio_${Date.now()}.wav`;
const audioPayload = {
    filename: `${userUid}-audio`,
    uri: recordingPath,
    type: 'audio/wav'
};

// Stream to server
request.upload({
    url: recordEndpoint,
    files: [audioPayload]
}).then(t => {
    t.on('progress', (written, total) => updateProgressBar(written, total));
    t.on('headerReceive', () => broadcastAudioID(audioId));
});

// Playback handler
const playConfig = {
    path: item.path,
    allowMetered: true,
    roaming: true
};

request.download(playConfig, (_, downloadObj) => {
    downloadObj.on('complete', () => {
        player.load(path: playConfig.outputPath);
        player.play();
    });
});

UI Integration Components

Emojis enhance user expression by integrating third-party visual librareis into the chat view.

<!-- Import external component -->
<element name="customEmojiSet" src="@/common/components/emojiPicker/index"/>

<!-- Display container when active -->
<div class="overlay-panel" condition="showFace">
    <div style="flex: 1">
        <text label="Available Expressions"/>
        <customEmojiSet/>
        <div style="flex: 1"/>
    </div>
</div>

Supported Features

The solution provides comprehensive messaging capabilities including rich text, images, files, audio, and emoticons. Additional functionalities cover peer management (add/remove/ban), authentication security, one-on-one and group chats, and profile customization via avatars and QR codes.

Tags: OpenHarmony Instant Messaging Network Programming Multiplayer Chat Media Handling

Posted on Tue, 26 May 2026 19:00:46 +0000 by eves