127 lines
4.5 KiB
Java
127 lines
4.5 KiB
Java
// Spark IM HTTP + TCP demo against production.
|
|
// javac docs/clients/SparkImClient.java && java -cp docs/clients SparkImClient
|
|
import java.io.ByteArrayInputStream;
|
|
import java.io.ByteArrayOutputStream;
|
|
import java.io.DataInputStream;
|
|
import java.io.DataOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.OutputStream;
|
|
import java.net.HttpURLConnection;
|
|
import java.net.InetSocketAddress;
|
|
import java.net.URI;
|
|
import java.net.URL;
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.List;
|
|
import java.util.zip.GZIPInputStream;
|
|
import javax.net.ssl.SNIHostName;
|
|
import javax.net.ssl.SSLParameters;
|
|
import javax.net.ssl.SSLSocket;
|
|
import javax.net.ssl.SSLSocketFactory;
|
|
|
|
public final class SparkImClient {
|
|
static final String API = "https://sparkapi.wyrs365.com";
|
|
static final String IM_HOST = "sparkim.wyrs365.com";
|
|
static final int IM_PORT = 443;
|
|
static final int HDR = 23;
|
|
static final long DEVICE_ID = 7;
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
String login = httpPost(API + "/v1/auth/login",
|
|
"{\"email\":\"test01@spark.com\",\"verify_code\":\"000000\",\"device_id\":"
|
|
+ DEVICE_ID + ",\"device_type\":\"android\",\"device_name\":\"demo\"}");
|
|
System.out.println("LOGIN " + login);
|
|
if (!login.contains("\"code\":\"0\"")) {
|
|
return;
|
|
}
|
|
String token = jsonString(login, "access_token");
|
|
|
|
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
|
|
SSLSocket socket = (SSLSocket) factory.createSocket();
|
|
SSLParameters params = socket.getSSLParameters();
|
|
params.setServerNames(List.of(new SNIHostName(IM_HOST)));
|
|
socket.setSSLParameters(params);
|
|
socket.connect(new InetSocketAddress(IM_HOST, IM_PORT), 10_000);
|
|
socket.startHandshake();
|
|
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
|
|
DataInputStream in = new DataInputStream(socket.getInputStream());
|
|
|
|
String auth = "{\"token\":\"" + token + "\",\"device_id\":" + DEVICE_ID
|
|
+ ",\"app_version\":\"1.0.0\",\"language\":\"zh-CN\"}";
|
|
write(out, 1, 1, auth);
|
|
System.out.println("AUTH " + read(in));
|
|
write(out, 2, 2, "");
|
|
System.out.println("HB " + read(in));
|
|
write(out, 4, 3, "{\"peer_id\":1,\"client_msg_id\":\"demo-1\",\"content\":{\"t\":1,\"text\":{\"body\":\"hi\"}}}");
|
|
System.out.println("SEND " + read(in));
|
|
socket.close();
|
|
}
|
|
|
|
static void write(DataOutputStream out, int cmd, int seq, String body) throws IOException {
|
|
byte[] b = body.getBytes(StandardCharsets.UTF_8);
|
|
ByteBuffer buf = ByteBuffer.allocate(HDR + b.length);
|
|
buf.putShort((short) 0x5350).put((byte) 1).putShort((short) cmd).putShort((short) 0)
|
|
.putLong(0).putInt(seq).putInt(b.length).put(b);
|
|
out.write(buf.array());
|
|
out.flush();
|
|
}
|
|
|
|
static String read(DataInputStream in) throws IOException {
|
|
byte[] h = in.readNBytes(HDR);
|
|
if (h.length < HDR) {
|
|
throw new IOException("short header");
|
|
}
|
|
ByteBuffer buf = ByteBuffer.wrap(h);
|
|
if (buf.getShort() != 0x5350) {
|
|
throw new IOException("magic");
|
|
}
|
|
buf.get();
|
|
int cmd = buf.getShort() & 0xffff;
|
|
int flags = buf.getShort() & 0xffff;
|
|
buf.getLong();
|
|
int seq = buf.getInt();
|
|
int n = buf.getInt();
|
|
byte[] body = in.readNBytes(n);
|
|
if ((flags & 1) != 0) {
|
|
body = gunzip(body);
|
|
}
|
|
return "cmd=" + cmd + " seq=" + seq + " " + new String(body, StandardCharsets.UTF_8);
|
|
}
|
|
|
|
static byte[] gunzip(byte[] body) throws IOException {
|
|
try (GZIPInputStream gz = new GZIPInputStream(new ByteArrayInputStream(body));
|
|
ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
|
|
gz.transferTo(bos);
|
|
return bos.toByteArray();
|
|
}
|
|
}
|
|
|
|
static String httpPost(String url, String json) throws IOException {
|
|
URL u = URI.create(url).toURL();
|
|
HttpURLConnection c = (HttpURLConnection) u.openConnection();
|
|
c.setRequestMethod("POST");
|
|
c.setDoOutput(true);
|
|
c.setRequestProperty("Content-Type", "application/json");
|
|
c.setRequestProperty("X-Language", "zh-CN");
|
|
c.setRequestProperty("X-App-Version", "1.0.0");
|
|
try (OutputStream os = c.getOutputStream()) {
|
|
os.write(json.getBytes(StandardCharsets.UTF_8));
|
|
}
|
|
int code = c.getResponseCode();
|
|
InputStream is = code >= 400 ? c.getErrorStream() : c.getInputStream();
|
|
try (InputStream in = is) {
|
|
return new String(in.readAllBytes(), StandardCharsets.UTF_8);
|
|
}
|
|
}
|
|
|
|
static String jsonString(String env, String key) {
|
|
int i = env.indexOf("\"" + key + "\"");
|
|
int colon = env.indexOf(':', i);
|
|
int a = env.indexOf('"', colon) + 1;
|
|
return env.substring(a, env.indexOf('"', a));
|
|
}
|
|
|
|
private SparkImClient() {}
|
|
}
|