startServer stopServer disconnectClient isClientConnected isClientDisconnected getAddress clientConnectListener serverReceiveDataListener sendToClient
connectServer disconnectServer isServerConnected isServerDisconnected serverDisonnectListener clientReceiveDataListener sendToServer
什么是Socket?
两个程序通过一个双向通信连接实现数据交互,这个连接就叫Socket。是网络模型中应用层与TCP/IP协议簇通信的中间软件抽象层,即对TCP/IP进行封装的一套API。应用层可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。socket可以支持不同的传输协议(TCP或UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接;同理,当使用UDP协议进行连接时,该Socket连接就是一个UDP连接。
Socket 通信逻辑流程:
1)服务端利用Socket监听端口;
2)客户端发起连接;
3)服务端返回信息,建立连接,开始通信;
4)客户端/服务端断开连接。
什么是粘包?
Socket 通讯是先将数据存放到缓冲区,然后发送到接受端的缓冲区,接收方再读取缓冲区的数据包。由于传输的过程为数据流,经过TCP传输后,三条数据被合并成了一条,这就是数据粘包。因为TCP使用了优化方法(Nagle算法)。它将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包。这么做优点也很明显,就是为了减少广域网的小分组数目,从而减小网络拥塞的出现。而UDP就不会有这种情况,它不会使用块的合并优化算法。当然除了优化算法,TCP和UDP都会因为下面两种情况造成粘包:1.发送端需要等缓冲区满才发送出去,造成粘包;2.接收方不及时接收缓冲区的包,造成多个包接收。
什么是断包?
断包应该还是比较好理解的,其原理同粘包。
插件概述
本插件封装了 Socket 相关功能接口,是建立的基于TCP的链接。可通过 startServer/stopServer 创建/停止服务端,客户端通过 connectServer 接口链接服务端,serverDisonnectListener可监听同服务端链接断开事件。服务端通过 clientConnectListener 监听客户端链接断开事件。serverReceiveDataListener、clientReceiveDataListener可分别监听对端发送过来的消息。本插件支持发送字符串消息,也支持发送各种类型的文件:pdf、txt、docx、ppt、mp3、mp4、png、jpeg等。
本插件是单例模式,在全局任何地方调用本插件都是同一个 socket 的实例对象。
本插件对粘包的解决方案
针对 Socket 粘包问题,本插件的处理逻辑:每次发送数据时,插件给数据封包,添加一个包头,在包头和包体之间设置一个分割符。收到数据后再进行拆包,拆包是按规定好的分割符进行拆包的。包头格式如下:
{
'type':'file', //字符串类型;file|string,发送的数据的类型,支持文件或字符串
'size':'10240', //字符串类型;发送的数据的大小,单位B
'fileName':'test.png'. //字符串类型;发送文件时,文件的名,发送字符串时本参数无意义
}
插件会自动识别数据的大小,生成一个包头(标准的 JSON 字符串),然后将包头和数据以及分割符转化成二进制数据并按照【包头分割符数据】的格式拼接。插件发送该封装好的数据包,Socket 会按照自己的逻辑粘包或者断包发送至对端缓冲区。对端先按照预设的分割符从缓冲区读取包头,提取包体 size 大小,然后再按 size 从缓冲区读取包体。此时得到的数据是二进制数据,插件再将之转化为原来的类型(字符串或文件)回调给前端开发者。
开启服务
startServer({params}, callback(ret, err))
charset:
port:
decollator:
ret:
{
status: true //布尔类型;服务创建是否成功
}
err:
{
msg:'' //字符串类型;开启服务失败信息
}
var AsyncSocket= api.require('AsyncSocket');
AsyncSocket.startServer({
port:3445
},function(ret, err) {
if (ret.status) {
console.log(JSON.stringify(ret));
} else {
console.log(JSON.stringify(err));
}
});
Android 系统,iOS 系统
可提供的 1.0.0 及更高版本
停止服务
stopServer()
var AsyncSocket= api.require('AsyncSocket');
AsyncSocket.stopServer();
Android 系统,iOS 系统
可提供的 1.0.0 及更高版本
目标客户端是否已经链接
isClientConnected({params},callback(ret))
IP:
port:
ret:
{
isConnected: true //布尔类型;是否链接
}
var AsyncSocket= api.require('AsyncSocket');
AsyncSocket.isClientConnected({
IP:'172.20.10.1',
port:3445
},function(ret) {
console.log(JSON.stringify(ret));
});
Android 系统,iOS 系统
可提供的 1.0.0 及更高版本
目标客户端是否已断开链接
isClientDisconnected({params},callback(ret))
IP:
port:
ret:
{
isDisconnected: true //布尔类型;是否断开链接
}
var AsyncSocket= api.require('AsyncSocket');
AsyncSocket.isClientDisconnected({
IP:'172.20.10.1',
port:3445
},function(ret) {
console.log(JSON.stringify(ret));
});
Android 系统,iOS 系统
可提供的 1.0.0 及更高版本
获取接收 IP 和端口号
getAddress(callback(ret, err))
ret:
{
status: true , //布尔类型;true|false
IP:'', //字符串类型;服务链接ip
port:80 //数字类型;服务端口号
}
err:
{
msg:'' //字符串类型;错误信息
}
var AsyncSocket= api.require('AsyncSocket');
AsyncSocket.getAddress(function(ret,err){
if (ret.status) {
console.log(JSON.stringify(ret));
} else {
console.log(JSON.stringify(err));
}
});
Android 系统,iOS 系统
可提供的 1.0.0 及更高版本
监听有客户端连接事件
clientConnectListener(callback(ret))
ret:
{
eventType:'', //字符串类型;交互事件类型;取值范围:
//connect:链接事件
//disconnect:断开链接事件 (android不支持)
IP:'', //字符串类型;客户端地址
port: //数字类型;客户端端口号
}
var AsyncSocket= api.require('AsyncSocket');
AsyncSocket.clientConnectListener(function(ret){
api.alert({msg:JSON.stringify(ret)});
});
Android 系统,iOS 系统
可提供的 1.0.0 及更高版本
监听客户端发送来数据的事件
serverReceiveDataListener(callback(ret))
ret:
{
eventType:'', //字符串类型;交互事件类型;取值范围:
//err:接受数据时发生错误
//receiveString:接收到字符串
//receiveFile:接收到文件
IP:'', //字符串类型;客户端地址
port: //数字类型;客户端端口号
filePath: //字符串类型;文件路径,仅当receiveFile时有值
string: //字符串类型;收到的字符串,仅当receiveString时有值
}
err:
{
msg:'' //字符串类型;错误信息
}
var AsyncSocket= api.require('AsyncSocket');
AsyncSocket.serverReceiveDataListener(function(ret){
api.alert({msg:JSON.stringify(ret)});
});
Android 系统,iOS 系统
可提供的 1.0.0 及更高版本
发送数据到客户端
sendToClient({params})
data:
type:
decollator:
IP:
port:
ret:
{
eventType:'', //字符串类型;交互事件类型;取值范围:
//error:发生错误
//complete:发送完成
//sending:发送中
partialLength: //数字类型;发送进度;仅当 sending 时有值
}
err:
{
msg:'' //字符串类型;错误信息
}
var ArgFace = api.require('AsyncSocket');
ArgFace.sendToClient({
data:'123456',
IP:'172.20.10.1',
port:3445
},function(ret,err){
api.alert({msg:JSON.stringify(ret)});
});
Android 系统,iOS 系统
可提供的 1.0.0 及更高版本
链接服务端
connectServer({params})
IP:
port:
decollator:
ret:
{
status: true, //布尔类型;true|false,操作是否成功
IP:'', //字符串类型;本地IP地址
port: //数字类型;本地和服务器通信的端口号
}
err:
{
msg:'' //字符串类型;错误信息
}
var AsyncSocket= api.require('AsyncSocket');
AsyncSocket.connectServer({
IP:'172.20.10.10',
port:3445
},function(ret, err) {
if (ret.status) {
console.log(JSON.stringify(ret));
} else {
console.log(JSON.stringify(err));
}
});
Android 系统,iOS 系统
可提供的 1.0.0 及更高版本
断开链接服务端
disconnectServer()
var AsyncSocket= api.require('AsyncSocket');
AsyncSocket.disconnectServer( );
Android 系统,iOS 系统
可提供的 1.0.0 及更高版本
是否已跟服务端链接
isServerConnected(callback(ret))
ret:
{
isConnected: true //布尔类型;是否链接
}
var AsyncSocket= api.require('AsyncSocket');
AsyncSocket.isServerConnected(function(ret) {
console.log(JSON.stringify(ret));
});
Android 系统,iOS 系统
可提供的 1.0.0 及更高版本
是否跟服务端端开链接
isServerDisconnected(callback(ret))
ret:
{
isDisconnected: true //布尔类型;是否断开链接
}
var AsyncSocket= api.require('AsyncSocket');
AsyncSocket.isServerDisconnected(function(ret) {
console.log(JSON.stringify(ret));
});
Android 系统,iOS 系统
可提供的 1.0.0 及更高版本
监听与服务端断开链接 (Android暂不支持)
serverDisonnectListener()
只有回调函数执行,无参数回调
var AsyncSocket= api.require('AsyncSocket');
AsyncSocket.serverDisonnectListener(function(ret){
api.alert({msg:JSON.stringify(ret)});
});
iOS 系统
可提供的 1.0.0 及更高版本
客户端收到消息监听
clientReceiveDataListener(callback(ret))
ret:
{
eventType:'', //字符串类型;交互事件类型;取值范围:
//err:接受数据时发生错误
//receiveString:接收到字符串
//receiveFile:接收到文件
IP:'', //字符串类型;服务端地址
port: //数字类型;服务端端口号
filePath: //字符串类型;文件路径,仅当receiveFile时有值
string: //字符串类型;收到的字符串,仅当receiveString时有值
}
err:
{
msg:'' //字符串类型;错误信息
}
var AsyncSocket= api.require('AsyncSocket');
AsyncSocket.clientReceiveDataListener(function(ret){
api.alert({msg:JSON.stringify(ret)});
});
Android 系统,iOS 系统
可提供的 1.0.0 及更高版本
发送数据到服务端
sendToServer({params})
data:
type:
decollator:
ret:
{
eventType:'', //字符串类型;交互事件类型;取值范围:
//error:发生错误
//complete:发送完成
//sending:发送中 (Android 不支持)
partialLength: //数字类型;发送进度;仅当 sending 时有值
}
err:
{
msg:'' //字符串类型;错误信息
}
var ArgFace = api.require('AsyncSocket');
ArgFace.sendToServer({
data:'123456',
IP:'172.20.10.1',
port:3445
},function(ret,err){
api.alert({msg:JSON.stringify(ret)});
});
Android 系统,iOS 系统
可提供的 1.0.0 及更高版本