socket.TCPSocketServer订阅'connect'事件,off掉之后,重新订阅,回调方法不生效。问题代码如下:
// 开启serverSocket监听
const tcpServer: socket.TCPSocketServer = socket.constructTCPSocketServerInstance();
let bindAddr: socket.NetAddress = {
address: '::',
port: 1111,
family: 25
};
// 设置TCPSocketServer连接的其他属性
const options: socket.TCPExtraOptions = {
keepAlive: true,
};
tcpServer.setExtraOptions(options);
tcpServer.listen(bindAddr).then(() => {
console.info(TAG, 'bind address success');
}).catch((err: BusinessError) => {
console.error(TAG, `server listen error : ${err.message}`);
});
// 订阅TCPSocketServer的事件
const connectCallBack = () => {
console.info('test');
};
tcpServer.on('connect', connectCallBack);
tcpServer.off('connect', connectCallBack);
// 回调不生效了
tcpServer.on('connect', connectCallBack); 根据官网文档on('connect')说明,listen方法调用成功后,才可调用此方法。因此on('connect')重新开启监听之前,重新调用listen并成功即可:
import { socket } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { util } from '@kit.ArkTS';
import { webview } from '@kit.ArkWeb';
let tcpServer: socket.TCPSocketServer = socket.constructTCPSocketServerInstance();
@Entry
@Component
struct tcpServerTest {
@State port: number = 8080;
@State running: boolean = false;
@State msgHistory: string = '';
@State webUrl: string = 'xx.com';
scroller: Scroller = new Scroller();
webScroller: Scroller = new Scroller();
controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Row(){
Text('端口')
.fontSize(15)
.height(40)
.alignRules({
left: { anchor: '__container__', align: HorizontalAlign.Start },
top: { anchor: 'txtTitle', align: VerticalAlign.Bottom }
})
.padding(10)
TextInput({ text: this.port.toString() })
.onChange((value) => {
this.port = parseInt(value);
})
.type(InputType.Number)
.width(80)
.height(40)
.fontSize(15)
.alignRules({
left: { anchor: 'txtPort', align: HorizontalAlign.End },
top: { anchor: 'txtPort', align: VerticalAlign.Top }
})
.padding(10)
Button(this.running ? '停止' : '启动')
.onClick(() => {
this.running = !this.running;
if (this.running) {
this.start();
} else {
this.stop();
}
})
.height(40)
.width(80)
.fontSize(15)
.alignRules({
right: { anchor: '__container__', align: HorizontalAlign.End },
top: { anchor: 'txtPort', align: VerticalAlign.Top }
})
.padding(10)
Button('重新订阅')
.onClick(() => {
this.start();
})
.alignRules({
left: { anchor: '__container__', align: HorizontalAlign.End },
top: { anchor: 'txtTitle', align: VerticalAlign.Top }
})
.padding(10)
.height(40)
}
Scroll(this.scroller) {
Text(this.msgHistory)
.textAlign(TextAlign.Start)
.padding(10)
.width('100%')
.fontSize(12)
.backgroundColor(0xeeeeee)
}
.alignRules({
left: { anchor: '__container__', align: HorizontalAlign.Start },
top: { anchor: 'butRun', align: VerticalAlign.Bottom }
})
.align(Alignment.Top)
.backgroundColor(0xeeeeee)
.height(200)
.scrollable(ScrollDirection.Vertical)
.scrollBar(BarState.On)
.scrollBarWidth(20)
.padding(10)
Row(){
Text('请求地址')
.id('txtUrl')
.fontSize(15)
.height(40)
.alignRules({
left: { anchor: '__container__', align: HorizontalAlign.Start },
top: { anchor: 'scrollHis', align: VerticalAlign.Bottom }
})
.padding(10)
TextInput({ text: this.webUrl.toString() })
.onChange((value) => {
this.webUrl = value;
})
.height(40)
.fontSize(15)
.padding(10)
.width(200)
Button('请求')
.onClick(() => {
this.controller.loadUrl(this.webUrl);
})
.height(40)
.width(80)
.fontSize(15)
.alignRules({
right: { anchor: '__container__', align: HorizontalAlign.End },
top: { anchor: 'txtUrl', align: VerticalAlign.Top }
})
.padding(10)
}
Scroll(this.webScroller) {
Web({ src: this.webUrl, controller: this.controller })
.padding(10)
.width('100%')
.backgroundColor(0xeeeeee)
.textZoomRatio(200)
.fileAccess(false)
.geolocationAccess(false)
}
.alignRules({
left: { anchor: '__container__', align: HorizontalAlign.Start },
top: { anchor: 'txtUrl', align: VerticalAlign.Bottom },
bottom: { anchor: '__container__', align: VerticalAlign.Bottom }
})
.backgroundColor(0xeeeeee)
.scrollable(ScrollDirection.Vertical)
.scrollBar(BarState.On)
.scrollBarWidth(20)
.align(Alignment.Top)
}
.height('100%')
.width('100%')
}
start() {
// 将url替换成有效的链接资源,例如使用本地环回地址
this.webUrl = 'xxx' + this.port.toString();
let listenAddr: socket.NetAddress = {
address: '0.0.0.0',
port: this.port,
family: 1
};
// listen方法调用成功后,调用on('connect')开启监听
tcpServer.listen(listenAddr, (err: BusinessError) => {
if (err) {
this.msgHistory += 'listen fail \r\n';
return;
}
this.msgHistory += 'listen success \r\n';
console.info('listen success');
tcpServer.on('connect', (clientSocket: socket.TCPSocketConnection) => {
console.info(`connect success: ${JSON.stringify(clientSocket)}`);
clientSocket.on('message', (msgInfo: socket.SocketMessageInfo) => {
let textDecoder = util.TextDecoder.create('utf-8');
let requestMsg = textDecoder.decodeToString(new Uint8Array(msgInfo.message));
let resp = buildRespString(requestMsg);
clientSocket.send({ data: resp });
});
});
});
}
// 关闭监听
stop() {
tcpServer.off('connect');
console.info('close listen connect');
}
}
//构造给客户端的应答内容
function buildRespString(content: string) {
let result: string = '';
let bodyContent = `<html><head><title>HTTP服务器模拟</title></head><body><h1>浏览器发送的请求信息</h1><pre><h2>${content}</h2></pre></body></html>`;
let textEncoder = new util.TextEncoder();
let contentBuf = textEncoder.encodeInto(bodyContent);
result += `HTTP/1.1 200 OK \r\nContent-Type: text/html; charset=utf-8 \r\nContent-Length: ${contentBuf.length} \r\n\r\n${bodyContent}`;
return result;
}