Data Transmission
Transmit payloads to the server using wx.sendSocketMessage() and monitor incomnig data through wx.onSocketMessage() callbacks.
const packet = JSON.stringify({ action: 'subscribe', channel: 'updates' });
wx.sendSocketMessage({
data: packet,
success: () => console.log('Payload dispatched')
});
wx.onSocketMessage((event) => {
const serverData = event.data;
console.log('Inbound message:', serverData);
});
Connection Terminasion
Properly closing a WebSocket requires ensuring the connection handshake has completed. Invoking wx.closeSocket() before wx.onSocketOpen fires will fail to terminate the connection.
wx.onSocketOpen(() => {
console.log('Socket ready state achieved');
// Safe to close only after connection establishment
wx.closeSocket({
code: 1000,
reason: 'User initiated disconnect'
});
});
wx.onSocketClose((res) => {
console.log('Socket terminated:', res.code, res.reason);
});
Building a Chat Interface
View Layer Structure
<view class="messaging-interface">
<scroll-view
class="conversation-stream"
scroll-y
scroll-into-view="{{anchorPoint}}"
enhanced
show-scrollbar
>
<block wx:for="{{dialogue}}" wx:key="timestamp">
<view id="msg-{{index}}" class="bubble {{item.self ? 'outbound' : 'inbound'}}">
{{item.content}}
</view>
</block>
</scroll-view>
<view class="composition-area">
<input
class="text-field"
placeholder="Enter message..."
bindinput="captureInput"
value="{{draftText}}"
confirm-type="send"
bindconfirm="submitMessage"
/>
<button class="transmit-btn" bindtap="submitMessage" disabled="{{!isReady}}">Send</button>
</view>
</view>
Logic Implementation
Page({
data: {
draftText: '',
dialogue: [],
anchorPoint: '',
isReady: false,
bufferQueue: [],
endpoint: 'wss://chat.example.com/v1/stream'
},
onLoad() {
this.establishTunnel();
},
onUnload() {
if (this.data.isReady) {
wx.closeSocket();
}
},
establishTunnel() {
const { endpoint } = this.data;
wx.connectSocket({
url: endpoint,
protocols: ['json']
});
wx.onSocketOpen(() => {
this.setData({ isReady: true });
this.processBuffer();
});
wx.onSocketError((err) => {
console.error('Tunnel establishment failed:', err);
wx.showToast({ title: 'Connection error', icon: 'error' });
});
wx.onSocketMessage((frame) => {
this.handleServerPayload(frame.data);
});
wx.onSocketClose(() => {
this.setData({ isReady: false });
});
},
processBuffer() {
const backlog = this.data.bufferQueue;
if (backlog.length === 0) return;
backlog.forEach(item => this.dispatch(item));
this.setData({ bufferQueue: [] });
},
handleServerPayload(rawData) {
const entry = {
content: rawData,
timestamp: Date.now(),
self: false
};
const updatedDialogue = [...this.data.dialogue, entry];
this.setData({
dialogue: updatedDialogue,
anchorPoint: `msg-${updatedDialogue.length - 1}`
});
},
captureInput(e) {
this.setData({ draftText: e.detail.value });
},
submitMessage() {
const text = this.data.draftText.trim();
if (!this.data.isReady) {
wx.showToast({ title: 'Offline', icon: 'none' });
return;
}
if (!text) {
wx.showToast({ title: 'Empty', icon: 'none' });
return;
}
this.dispatch(text);
// Optimistic UI update
const localEntry = {
content: text,
timestamp: Date.now(),
self: true
};
this.setData({
dialogue: [...this.data.dialogue, localEntry],
draftText: ''
});
},
dispatch(payload) {
if (this.data.isReady) {
wx.sendSocketMessage({ data: payload });
} else {
const queue = this.data.bufferQueue;
queue.push(payload);
this.setData({ bufferQueue: queue });
}
}
});