【安卓学习之socket】socket.io-client
介绍
io.socket.client.Socket 是由 Socket.IO 团队开发的,其核心维护者为 Automattic 公司(即 WordPress 背后的公司)。
广泛用于 Android 应用中实现实时消息、聊天、通知等功能
地址
https://mvnrepository.com/artifact/io.socket/socket.io-client/versions
https://repo.maven.apache.org/maven2/io/socket/engine.io-client/
https://github.com/socketio/socket.io-client-java
https://gitee.com/hanmtou/socket.io-client-java
依赖
c
implementation 'io.socket:socket.io-client:2.1.2'
问题
想知道这个怎么将 JSONObject 发送出去
c
/**
* 初始化配置
*/
public void init() {
this.mClient = new SocketClient.Builder().url(this.mUrl)
.auth(UserId, Token)
.socketMessageListener(this)
.socketMapListen("auth", this.onAuthListener)
.socketMapListen("index", this.onAuthListener)
.socketMapListen("User", this.onUserListener)
.socketMapListen("Notify", this.onNotifyListener)
.socketMapListen("Message", this.onMessageListener)
.socketMapListen("message", this.onRtcSdpMessageListener)
.socketMapListen("quite", this.onQuiteListener).build();
}
/**
* 发送消息,暂不重载
*/
public void send() {
JSONObject jSONObject = new JSONObject();
jSONObject.put("replayId", Id);
jSONObject.put("type", "candidate");
jSONObject.put("label", sdpMLineIndex);// int
jSONObject.put("id", sdpMid);// String
jSONObject.put("candidate", sdp);// String
this.mClient.emit(jSONObject);
}
c
public class SocketClient {
private final Emitter.Listener mConnectListener,mErrorListener,mTimeOutListener;
private final Emitter.Listener mReConnectListener,mRePingListener,mRePongListener;
private Map<String, Emitter.Listener> mListenerMap;
public SocketMessageListener mListener;
public SocketClient(Builder builder) {
if (!TextUtils.isEmpty(builder.url)) {
try {
IO.Options options = new IO.Options();
options.forceNew = true;
options.reconnection = true;
options.reconnectionDelay = 10000;
options.query = "uid=" + builder.uid + "&token=" + builder.token + "&device=1";
mSocket = IO.socket(builder.url, options);
mSocket .on(Socket.EVENT_CONNECT, mConnectListener);
mSocket.on(Socket.EVENT_DISCONNECT, mDisConnectListener);
mSocket.on(Socket.EVENT_CONNECT_ERROR, mErrorListener);
mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, mTimeOutListener);
mSocket.on(Socket.EVENT_RECONNECT, mReConnectListener);
mSocket.on(Socket.EVENT_PING, mRePingListener);
mSocket.on(Socket.EVENT_PONG, mRePongListener);
mListenerMap = builder.listenerMap;
if (mListenerMap!= null) {
for (Map.Entry next : mListenerMap.entrySet()) {
this.mSocket.on((String) next.getKey(), (Emitter.Listener) next.getValue());
}
}
mListener = builder.listener;
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void connect() {
if (mSocket!= null) {
mSocket.connect();
}
}
public void disConnect() {
if (mSocket!= null) {
mSocket.close();
mSocket.off();
}
}
public void emit(JSONObject jSONObject) {
mSocket.emit("Message", jSONObject);
}
}
分析
c
/**
* The socket class for Socket.IO Client.
*/
public class Socket extends Emitter {
private int ids;
private String nsp;
private Manager io;
/**
* 触发一个事件。当你在最后一个参数中传递 {@link Ack} 时,则会执行确认回调。
*
* @param event 事件名称
* @param args 要发送的数据(最后一个参数可能是应答事件)
* @return 此对象的引用
*/
@Override
public Emitter emit(final String event, final Object... args) {
if (RESERVED_EVENTS.containsKey(event)) {
throw new RuntimeException("'" + event + "' is a reserved event name");
}
EventThread.exec(new Runnable() {
@Override
public void run() {
Ack ack;
Object[] _args;
int lastIndex = args.length - 1;
if (args.length > 0 && args[lastIndex] instanceof Ack) {
_args = new Object[lastIndex];
for (int i = 0; i < lastIndex; i++) {
_args[i] = args[i];
}
ack = (Ack) args[lastIndex];
} else {
_args = args;
ack = null;
}
emit(event, _args, ack);
}
});
return this;
}
/**
* 触发一个带确认回调的事件
*
* @param event 事件名称
* @param args 要发送的数据
* @param ack 要调用的确认回调
* @return 此对象的引用
*/
public Emitter emit(final String event, final Object[] args, final Ack ack) {
EventThread.exec(new Runnable() {
@Override
public void run() {
JSONArray jsonArgs = new JSONArray();
jsonArgs.put(event);
if (args != null) {
for (Object arg : args) {
jsonArgs.put(arg);
}
}
// ===== 这边 type 是 EVENT 类型
Packet<JSONArray> packet = new Packet<>(Parser.EVENT, jsonArgs);
if (ack != null) {
logger.fine(String.format("emitting packet with ack id %d", ids));
Socket.this.acks.put(ids, ack);
packet.id = ids++;
}
if (Socket.this.connected) {
Socket.this.packet(packet);
} else {
Socket.this.sendBuffer.add(packet);
}
}
});
return this;
}
/**
* 发送
*/
private void packet(Packet packet) {
packet.nsp = this.nsp;
this.io.packet(packet);
}
}
c
public class Packet<T> {
public int type = -1;// ===== 这边 type 是 EVENT 类型
public int id = -1;
public String nsp;
public T data;// ===== 这边 data 是 JSONArray 类型,第一个参数是"Message", 第二个参数是 JSONObject
public int attachments;
public Packet(int type, T data) {
this.type = type;
this.data = data;
}
}
c
/**
* Manager class represents a connection to a given Socket.IO server.
*/
public class Manager extends Emitter {
private Parser.Encoder encoder;
private Parser.Decoder decoder;
public Manager(URI uri, Options opts) {
this.opts = opts;
this.nsps = new ConcurrentHashMap<>();
this.subs = new LinkedList<>();
this.timeout(opts.timeout);
this.readyState = ReadyState.CLOSED;
this.uri = uri;
this.encoding = false;
this.encoder = opts.encoder != null ? opts.encoder : new IOParser.Encoder();
this.decoder = opts.decoder != null ? opts.decoder : new IOParser.Decoder();
}
void packet(Packet packet) {
if (logger.isLoggable(Level.FINE)) {
logger.fine(String.format("writing packet %s", packet));
}
final Manager self = this;
if (!self.encoding) {
self.encoding = true;
this.encoder.encode(packet, new Parser.Encoder.Callback() {
@Override
public void call(Object[] encodedPackets) {
for (Object packet : encodedPackets) {
if (packet instanceof String) {
self.engine.write((String)packet);
} else if (packet instanceof byte[]) {
self.engine.write((byte[])packet);
}
}
self.encoding = false;
self.processPacketQueue();
}
});
} else {
self.packetBuffer.add(packet);
}
}
}
io.socket.parser.IOParser.java
c
final public class IOParser implements Parser {
@Override
public void encode(Packet obj, Callback callback) {
// ===== 这边 type 是 EVENT 类型
// ===== 这边 data 是 JSONArray 类型,第一个参数是"Message", 第二个参数是 JSONObject
// HasBinary.hasBinary(obj.data) 的调用结果应该是false
if ((obj.type == EVENT || obj.type == ACK) && HasBinary.hasBinary(obj.data)) {
obj.type = obj.type == EVENT ? BINARY_EVENT : BINARY_ACK;
}
if (logger.isLoggable(Level.FINE)) {
logger.fine(String.format("encoding packet %s", obj));
}
if (BINARY_EVENT == obj.type || BINARY_ACK == obj.type) {
encodeAsBinary(obj, callback);
} else {
String encoding = encodeAsString(obj);// ===== 执行到这边 按照字符串处理
callback.call(new String[] {encoding});
}
}
private String encodeAsString(Packet obj) {
StringBuilder str = new StringBuilder("" + obj.type);
if (BINARY_EVENT == obj.type || BINARY_ACK == obj.type) {
str.append(obj.attachments);
str.append("-");
}
if (obj.nsp != null && obj.nsp.length() != 0 && !"/".equals(obj.nsp)) {
str.append(obj.nsp);
str.append(",");
}
if (obj.id >= 0) {
str.append(obj.id);
}
if (obj.data != null) {
str.append(obj.data);
}
if (logger.isLoggable(Level.FINE)) {
logger.fine(String.format("encoded %s as %s", obj, str));
}
return str.toString();
}
}
io.socket.hasbinary.HasBinary.java
c
/**
* 检测传入对象 obj.data 中是否包含二进制数据(如 Buffer、Blob、ArrayBuffer 等)。
* 这个检测对于决定如何处理和编码数据包至关重要
*/
public class HasBinary {
private static final Logger logger = Logger.getLogger(HasBinary.class.getName());
private HasBinary() {}
public static boolean hasBinary(Object data) {
return _hasBinary(data);
}
private static boolean _hasBinary(Object obj) {
if (obj == null) return false;
if (obj instanceof byte[]) {
return true;
}
if (obj instanceof JSONArray) {// == 第1次执行这个(JSONArray 中的 第一个参数是"Message")
JSONArray _obj = (JSONArray)obj;
int length = _obj.length();// 长度为2
for (int i = 0; i < length; i++) {
Object v;
try {
v = _obj.isNull(i) ? null : _obj.get(i);
} catch (JSONException e) {
logger.log(Level.WARNING, "An error occured while retrieving data from JSONArray", e);
return false;
}
if (_hasBinary(v)) {
return true;
}
}
} else if (obj instanceof JSONObject) {// == 第2次执行这个(JSONArray 中的 第二个参数是 JSONObject)
JSONObject _obj = (JSONObject)obj;
Iterator keys = _obj.keys();
while (keys.hasNext()) {
String key = (String)keys.next();
Object v;
try {
v = _obj.get(key);
} catch (JSONException e) {
logger.log(Level.WARNING, "An error occured while retrieving data from JSONObject", e);
return false;
}
if (_hasBinary(v)) {
return true;
}
}
}
return false;
}
}
█ 相关资料
提示:这里是参考的相关文章
█ 免责声明
| 博主分享的所有文章内容,部分参考网上教程,引用大神高论,部分亲身实践,记下笔录,内容可能存在诸多不实之处,还望海涵,本内容仅供学习研究使用,切勿用于商业用途,若您是部分内容的作者,不喜欢此内容被分享出来,可联系博主说明相关情况通知删除,感谢您的理解与支持! |
|---|
转载请注明出处:
https://blog.csdn.net/ljb568838953/article/details/159728410