[*] android信令接入

This commit is contained in:
acgist
2023-03-29 08:16:04 +08:00
parent fcca3c90aa
commit f68119fd30
32 changed files with 397 additions and 128 deletions

View File

@@ -55,7 +55,7 @@ build/target/product/handheld_*.mk
```
source build/envsetup.sh
lunch aosp_arm64-user
make -j 8
make -j 16
make udpatepackage
```

View File

@@ -12,6 +12,7 @@
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true">
<activity
android:name=".MainActivity"

View File

@@ -19,6 +19,7 @@ public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i(BootReceiver.class.getSimpleName(), "onReceive");
final Resources resources = context.getResources();
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
if(resources.getBoolean(R.bool.preview)) {

View File

@@ -1,18 +1,22 @@
package com.acgist.taoyao.client;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Process;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.acgist.taoyao.client.databinding.ActivityMainBinding;
import java.io.Serializable;
/**
* 预览界面
*
@@ -20,10 +24,12 @@ import com.acgist.taoyao.client.databinding.ActivityMainBinding;
*/
public class MainActivity extends AppCompatActivity {
private MainHandler mainHandler;
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle bundle) {
Log.i(MainActivity.class.getSimpleName(), "onCreate");
super.onCreate(bundle);
// 启动点亮屏幕
this.setTurnScreenOn(true);
@@ -37,22 +43,27 @@ public class MainActivity extends AppCompatActivity {
this.binding = ActivityMainBinding.inflate(this.getLayoutInflater());
this.setContentView(this.binding.getRoot());
// 设置按钮
this.binding.settings.setOnClickListener(view -> {
final Intent settings = new Intent(this, SettingsActivity.class);
this.startActivity(settings);
});
this.binding.settings.setOnClickListener(this::launchSettings);
}
@Override
protected void onStart() {
Log.i(MainActivity.class.getSimpleName(), "onStart");
super.onStart();
}
@Override
protected void onStop() {
Log.i(MainActivity.class.getSimpleName(), "onStop");
super.onStop();
}
@Override
protected void onDestroy() {
Log.i(MainActivity.class.getSimpleName(), "onDestroy");
super.onDestroy();
}
/**
* 拉起媒体服务
*/
@@ -63,13 +74,42 @@ public class MainActivity extends AppCompatActivity {
SystemClock.sleep(100);
}
if(display.STATE_ON == display.getState()) {
// 媒体服务
Log.i(MainActivity.class.getSimpleName(), "拉起媒体服务");
final Intent mediaService = new Intent(this, MediaService.class);
this.startService(mediaService);
final Intent intent = new Intent(this, MediaService.class);
if(this.mainHandler == null) {
this.mainHandler = new MainHandler();
}
intent.putExtra("mainHandler", this.mainHandler);
intent.setAction("connect");
this.startService(intent);
} else {
Log.w(MainActivity.class.getSimpleName(), "拉起媒体服务失败");
}
}
/**
* 拉起设置页面
*
* @param view View
*/
private void launchSettings(View view) {
final Intent intent = new Intent(this, SettingsActivity.class);
this.startActivity(intent);
}
/**
* Handler
*
* @author acgist
*/
private static class MainHandler extends Handler implements Serializable {
@Override
public void handleMessage(@NonNull Message message) {
super.handleMessage(message);
Log.d(MainActivity.class.getSimpleName(), "Handler消息" + message.what + " - " + message.obj);
}
}
}

View File

@@ -1,9 +1,18 @@
package com.acgist.taoyao.client;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.location.LocationManager;
import android.net.wifi.WifiManager;
import android.os.BatteryManager;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
import com.acgist.taoyao.client.signal.Taoyao;
@@ -18,17 +27,85 @@ public class MediaService extends Service {
System.loadLibrary("taoyao");
}
public MediaService() {
}
private Taoyao taoyao;
private Handler mainHandler;
@Override
public void onCreate() {
Log.i(MediaService.class.getSimpleName(), "onCreate");
super.onCreate();
Log.d(MediaService.class.getSimpleName(), "启动媒体服务");
}
@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
Log.i(MediaService.class.getSimpleName(), "onBind");
return new Binder();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(MediaService.class.getSimpleName(), "onStartCommand");
if("connect".equals(intent.getAction())) {
if(this.taoyao == null) {
Log.d(MediaService.class.getSimpleName(), "打开信令连接");
this.mainHandler = (Handler) intent.getSerializableExtra("mainHandler");
this.connect();
} else {
Log.d(MediaService.class.getSimpleName(), "信令已经连接");
}
} else if("reconnect".equals(intent.getAction())) {
Log.d(MediaService.class.getSimpleName(), "重新连接信令");
this.connect();
} else {
Log.w(MediaService.class.getSimpleName(), "未知动作:" + intent.getAction());
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.i(MediaService.class.getSimpleName(), "onDestroy");
super.onDestroy();
this.close();
}
/**
* 连接信令
*/
private synchronized void connect() {
// 加载配置
final SharedPreferences sharedPreferences = this.getSharedPreferences("settings", Context.MODE_PRIVATE);
final int port = sharedPreferences.getInt("settings.port", 9999);
final String host = sharedPreferences.getString("settings.host", "192.168.1.100");
final String name = sharedPreferences.getString("settings.name", "移动端");
final String clientId = sharedPreferences.getString("settings.clientId", "mobile");
final String username = sharedPreferences.getString("settings.username", "taoyao");
final String password = sharedPreferences.getString("settings.password", "taoyao");
final Resources resources = this.getResources();
// 系统服务
final Context context = this.getApplicationContext();
final WifiManager wifiManager = context.getSystemService(WifiManager.class);
final BatteryManager batteryManager = context.getSystemService(BatteryManager.class);
final LocationManager locationManager = context.getSystemService(LocationManager.class);
this.close();
// 连接信令
this.taoyao = new Taoyao(
port, host, resources.getString(R.string.version),
name, clientId, resources.getString(R.string.clientType), username, password,
resources.getInteger(R.integer.timeout), resources.getString(R.string.encrypt), resources.getString(R.string.encryptSecret),
this.mainHandler, context,
wifiManager, batteryManager, locationManager
);
Toast.makeText(this.getApplicationContext(), "连接信令", Toast.LENGTH_SHORT).show();
}
private synchronized void close() {
if(this.taoyao == null) {
return;
}
Toast.makeText(this.getApplicationContext(), "关闭信令", Toast.LENGTH_SHORT).show();
this.taoyao.close();
this.taoyao = null;
}
}

View File

@@ -1,8 +1,11 @@
package com.acgist.taoyao.client;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
@@ -19,22 +22,79 @@ public class SettingsActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.i(SettingsActivity.class.getSimpleName(), "onCreate");
super.onCreate(savedInstanceState);
// 布局
this.binding = ActivitySettingsBinding.inflate(this.getLayoutInflater());
this.setContentView(this.binding.getRoot());
// 设置按钮
this.binding.connect.setOnClickListener(view -> {
this.binding.connect.setOnClickListener(this::settingsPersistent);
}
@Override
protected void onStart() {
Log.i(SettingsActivity.class.getSimpleName(), "onStart");
super.onStart();
// 回填配置
final SharedPreferences sharedPreferences = this.getSharedPreferences("settings", Context.MODE_PRIVATE);
this.binding.port.setText(String.valueOf(sharedPreferences.getInt("settings.port", 9999)));
this.binding.host.setText(sharedPreferences.getString("settings.host", "192.168.1.100"));
this.binding.name.setText(sharedPreferences.getString("settings.name", "移动端"));
this.binding.clientId.setText(sharedPreferences.getString("settings.clientId", "mobile"));
this.binding.username.setText(sharedPreferences.getString("settings.username", "taoyao"));
this.binding.password.setText(sharedPreferences.getString("settings.password", "taoyao"));
}
@Override
protected void onStop() {
Log.i(SettingsActivity.class.getSimpleName(), "onStop");
super.onStop();
}
@Override
protected void onDestroy() {
Log.i(SettingsActivity.class.getSimpleName(), "onDestroy");
super.onDestroy();
}
/**
* 持久化日志
*
* @param view View
*/
private void settingsPersistent(View view) {
final String port = this.binding.port.getText().toString();
final String name = this.binding.name.getText().toString();
final String host = this.binding.host.getText().toString();
// final Taoyao taoyao = new Taoyao(
//
// );
// Log.d(SettingsActivity.class.getSimpleName(), "连接信令:" + taoyao);
final Intent main = new Intent(this, MainActivity.class);
this.startActivity(main);
});
final String name = this.binding.name.getText().toString();
final String clientId = this.binding.clientId.getText().toString();
final String username = this.binding.username.getText().toString();
final String password = this.binding.password.getText().toString();
Log.i(SettingsActivity.class.getSimpleName(), String.format("""
端口:%s
地址:%s
名称:%s
标识:%s
用户:%s
密码:%s
""", port, host, name, clientId, username, password));
// 保存配置
final SharedPreferences sharedPreferences = this.getSharedPreferences("settings", Context.MODE_PRIVATE);
final SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt("settings.port", Integer.parseInt(port));
editor.putString("settings.host", host);
editor.putString("settings.name", name);
editor.putString("settings.clientId", clientId);
editor.putString("settings.username", username);
editor.putString("settings.password", password);
editor.commit();
// 重连
final Intent intent = new Intent(this, MediaService.class);
intent.setAction("reconnect");
this.startService(intent);
// 返回预览页面
this.startActivity(new Intent(this, MainActivity.class));
// 结束
this.finish();
}
}

View File

@@ -1,4 +0,0 @@
package com.acgist.taoyao.client.media;
public class AudioPublisher {
}

View File

@@ -1,7 +0,0 @@
package com.acgist.taoyao.client.media;
/**
* 终端
*/
public class Client {
}

View File

@@ -1,4 +0,0 @@
package com.acgist.taoyao.client.media;
public class VideoPublisher {
}

View File

@@ -6,8 +6,10 @@ import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.BatteryManager;
import android.os.Handler;
import android.util.Log;
import androidx.core.app.ActivityCompat;
@@ -18,7 +20,7 @@ import com.acgist.taoyao.boot.model.MessageCode;
import com.acgist.taoyao.boot.model.MessageCodeException;
import com.acgist.taoyao.boot.utils.CloseableUtils;
import com.acgist.taoyao.boot.utils.JSONUtils;
import com.acgist.taoyao.client.media.Recorder;
import com.acgist.media.ClientRecorder;
import com.acgist.taoyao.client.utils.IdUtils;
import org.apache.commons.lang3.ArrayUtils;
@@ -52,6 +54,8 @@ import javax.crypto.spec.SecretKeySpec;
*/
public final class Taoyao {
private static final long MAX_TIMEOUT = 60L * 1000;
/**
* 端口
*/
@@ -87,15 +91,19 @@ public final class Taoyao {
/**
* 是否关闭
*/
private boolean close;
private volatile boolean close;
/**
* 是否连接
*/
private boolean connect;
private volatile boolean connect;
/**
* 超时时间
*/
private final int timeout;
/**
* 重试次数
*/
private int connectRetryTimes;
/**
* Socket
*/
@@ -116,6 +124,10 @@ public final class Taoyao {
* 解密工具
*/
private final Cipher decrypt;
/**
* Handler
*/
private final Handler handler;
/**
* 服务上下文
*/
@@ -144,16 +156,13 @@ public final class Taoyao {
* 定时任务线程池
*/
private final ScheduledExecutorService scheduled;
/**
* 全局单例
*/
private static Taoyao instance;
public Taoyao(
int port, String host, String version,
String name, String clientId, String clientType, String username, String password,
int timeout, String algo, String secret,
Context context, WifiManager wifiManager, BatteryManager batteryManager, LocationManager locationManager
Handler handler, Context context,
WifiManager wifiManager, BatteryManager batteryManager, LocationManager locationManager
) {
this.close = false;
this.connect = false;
@@ -166,9 +175,11 @@ public final class Taoyao {
this.username = username;
this.password = password;
this.timeout = timeout;
this.connectRetryTimes = 1;
final boolean plaintext = algo == null || algo.isEmpty() || algo.equals("PLAINTEXT");
this.encrypt = plaintext ? null : this.buildCipher(Cipher.ENCRYPT_MODE, algo, secret);
this.decrypt = plaintext ? null : this.buildCipher(Cipher.DECRYPT_MODE, algo, secret);
this.handler = handler;
this.context = context;
this.wifiManager = wifiManager;
this.batteryManager = batteryManager;
@@ -178,19 +189,8 @@ public final class Taoyao {
this.executor = Executors.newFixedThreadPool(3);
// 心跳线程
this.scheduled = Executors.newScheduledThreadPool(1);
executor.submit(this::loopMessage);
scheduled.scheduleWithFixedDelay(this::heartbeat, 30, 30, TimeUnit.SECONDS);
if(Taoyao.instance != null) {
Taoyao.instance.close();
}
Taoyao.instance = this;
}
/**
* @return 信令
*/
public static final Taoyao getInstance() {
return Taoyao.instance;
this.executor.submit(this::loopMessage);
this.scheduled.scheduleWithFixedDelay(this::heartbeat, 30, 30, TimeUnit.SECONDS);
}
/**
@@ -215,9 +215,9 @@ public final class Taoyao {
/**
* 连接信令
*/
public synchronized void connect() {
public synchronized boolean connect() {
if(this.close) {
return;
return false;
}
// 释放连接
this.disconnect();
@@ -233,13 +233,17 @@ public final class Taoyao {
this.output = this.socket.getOutputStream();
this.register();
this.connect = true;
this.connectRetryTimes = 1;
synchronized (this) {
this.notifyAll();
}
} else {
this.connect = false;
}
} catch (Exception e) {
Log.e(Taoyao.class.getSimpleName(), "连接信令异常:" + this.host + ":" + this.port, e);
}
return this.connect;
}
/**
@@ -256,7 +260,17 @@ public final class Taoyao {
while (!this.close && !this.connect) {
this.connect();
synchronized (this) {
this.wait(this.timeout);
try {
long timeout = this.timeout;
if(MAX_TIMEOUT > this.timeout * this.connectRetryTimes) {
timeout = this.timeout * this.connectRetryTimes++;
} else {
timeout = MAX_TIMEOUT;
}
this.wait(timeout);
} catch (InterruptedException e) {
Log.d(Taoyao.class.getSimpleName(), "信令等待异常", e);
}
}
}
// 读取
@@ -300,7 +314,9 @@ public final class Taoyao {
}
} catch (Exception e) {
Log.e(Taoyao.class.getSimpleName(), "接收信令异常", e);
this.connect();
if(this.socket.isClosed()) {
this.disconnect();
}
}
}
}
@@ -340,6 +356,7 @@ public final class Taoyao {
Log.w(Taoyao.class.getSimpleName(), "通道没有打开:" + message);
return;
}
Log.i(Taoyao.class.getSimpleName(), "发送信令:" + message);
try {
this.output.write(this.encrypt(message));
} catch (Exception e) {
@@ -375,7 +392,10 @@ public final class Taoyao {
/**
* 释放连接
*/
private void disconnect() {
private synchronized void disconnect() {
if(!this.connect) {
return;
}
Log.d(Taoyao.class.getSimpleName(), "释放信令:" + this.host + ":" + this.port);
this.connect = false;
CloseableUtils.close(this.input);
@@ -389,11 +409,15 @@ public final class Taoyao {
/**
* 关闭信令
*/
private void close() {
this.disconnect();
public synchronized void close() {
if(this.close) {
return;
}
Log.d(Taoyao.class.getSimpleName(), "关闭信令:" + this.host + ":" + this.port);
this.close = true;
executor.shutdownNow();
scheduled.shutdownNow();
this.disconnect();
this.executor.shutdownNow();
this.scheduled.shutdownNow();
}
/**
@@ -474,10 +498,10 @@ public final class Taoyao {
"clientType", this.clientType,
"latitude", location == null ? -1 : location.getLatitude(),
"longitude", location == null ? -1 : location.getLongitude(),
"signal", this.wifiManager == null ? -1 : this.wifiManager.getMaxSignalLevel(),
"batter", this.batteryManager == null ? -1 : this.batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY),
"charging", this.batteryManager == null ? -1 : this.batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_STATUS),
"recording", Recorder.getInstance().isActive()
"signal", this.wifiSignal(),
"battery", this.battery(),
"charging", this.charging(),
"recording", ClientRecorder.getInstance().isActive()
));
}
@@ -497,18 +521,51 @@ public final class Taoyao {
* 心跳
*/
private void heartbeat() {
while(!this.close) {
if(this.close || !this.connect) {
return;
}
final Location location = this.location();
this.push(this.buildMessage(
"client::heartbeat",
"latitude", location == null ? -1 : location.getLatitude(),
"longitude", location == null ? -1 : location.getLongitude(),
"signal", this.wifiManager == null ? -1 : this.wifiManager.getMaxSignalLevel(),
"batter", this.batteryManager == null ? -1 : this.batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY),
"charging", this.batteryManager == null ? -1 : this.batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_STATUS),
"recording", Recorder.getInstance().isActive()
"signal", this.wifiSignal(),
"battery", this.battery(),
"charging", this.charging(),
"recording", ClientRecorder.getInstance().isActive()
));
}
/**
* @return 电量百分比
*/
private int battery() {
return this.batteryManager == null ? -1 : this.batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
}
/**
* @return 充电状态
*/
private boolean charging() {
return
this.batteryManager == null ?
false :
this.batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_STATUS) == BatteryManager.BATTERY_STATUS_CHARGING;
}
/**
* @return WIFI信号强度
*/
private int wifiSignal() {
if(this.wifiManager == null) {
return -1;
}
final WifiInfo wifiInfo = this.wifiManager.getConnectionInfo();
if(wifiInfo == null) {
return -1;
}
final int signal = this.wifiManager.calculateSignalLevel(wifiInfo.getRssi());
return signal / this.wifiManager.getMaxSignalLevel() * 100;
}
/**

View File

@@ -15,7 +15,6 @@
android:hint="@string/signal_port"
android:importantForAutofill="no"
android:inputType="number"
android:text="9999"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
@@ -29,7 +28,6 @@
android:hint="@string/signal_host"
android:importantForAutofill="no"
android:inputType="text"
android:text="192.168.0.100"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintLeft_toLeftOf="parent"
@@ -46,7 +44,6 @@
android:hint="@string/signal_name"
android:importantForAutofill="no"
android:inputType="text"
android:text="mobile"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintLeft_toLeftOf="parent"
@@ -63,7 +60,6 @@
android:hint="@string/signal_client_id"
android:importantForAutofill="no"
android:inputType="text"
android:text="mobile"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintLeft_toLeftOf="parent"
@@ -80,7 +76,6 @@
android:hint="@string/signal_username"
android:importantForAutofill="no"
android:inputType="text"
android:text="taoyao"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintLeft_toLeftOf="parent"
@@ -97,7 +92,6 @@
android:hint="@string/signal_password"
android:importantForAutofill="no"
android:inputType="textPassword"
android:text="taoyao"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintLeft_toLeftOf="parent"

View File

@@ -2,7 +2,6 @@
<resources>
<color name="white">#FFFFFFFF</color>
<color name="black">#FF000000</color>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>

View File

@@ -8,8 +8,8 @@
<integer name="timeout">5000</integer>
<!-- 终端类型CAMERA|MOBILE -->
<string name="clientType">MOBILE</string>
<!--信令加密算法-->
<string name="algo">DES</string>
<!--信令加密密钥-->
<string name="secret">DES</string>
<!-- 信令加密策略AES|DES -->
<string name="encrypt">DES</string>
<!-- 信令加密密钥 -->
<string name="encryptSecret">2SPWy+TF1zM=</string>
</resources>

View File

@@ -0,0 +1,4 @@
package com.acgist.media;
public class AudioPublisher {
}

View File

@@ -1,20 +1,20 @@
package com.acgist.taoyao.client.media;
package com.acgist.media;
/**
* 录像机
*
* @author acgist
*/
public final class Recorder {
public final class ClientRecorder {
/**
* 是否正在录像
*/
private boolean active;
private static final Recorder INSTANCE = new Recorder();
private static final ClientRecorder INSTANCE = new ClientRecorder();
public static final Recorder getInstance() {
public static final ClientRecorder getInstance() {
return INSTANCE;
}

View File

@@ -0,0 +1,12 @@
package com.acgist.media;
/**
* 房间终端
*
* @author acgist
*/
public class RoomClient {
}

View File

@@ -0,0 +1,4 @@
package com.acgist.media;
public class VideoPublisher {
}

View File

@@ -1,6 +1,7 @@
const config = require("./Config.js");
const process = require("child_process");
const WebSocket = require("ws");
const { trace } = require("console");
/**
* 信令协议
@@ -1383,7 +1384,12 @@ class Taoyao {
});
// await transport.enableTraceEvent([ 'probation', 'bwe' ]);
// transport.on("trace", (trace) => {
// // 网络评估
// if (trace.type === "bwe" && trace.direction === "out") {
// logger.debug("transport downlinkBwe", trace);
// } else {
// console.debug("transport trace", transport.id, trace);
// }
// });
transport.observer.on("close", () => {
if(room.transports.delete(transport.id)) {

View File

@@ -52,7 +52,7 @@ public class SocketProperties {
@Schema(title = "加密策略", description = "加密策略")
private Encrypt encrypt;
@Schema(title = "加密密钥", description = "加密密钥:为空自动生成")
private String encryptKey;
private String encryptSecret;
@Schema(title = "超时时间", description = "超时时间")
private Long timeout;
@Schema(title = "队列长度", description = "队列长度")

View File

@@ -10,7 +10,6 @@ public class TaoyaoApplication {
public static void main(String[] args) {
SpringApplication.run(TaoyaoApplication.class, args);
// System.exit(SpringApplication.exit(SpringApplication.run(TaoyaoApplication.class, args)));
}
}

View File

@@ -150,7 +150,7 @@ taoyao:
host: 0.0.0.0
port: 9999
encrypt: DES
encrypt-key: 2SPWy+TF1zM=
encrypt-secret: 2SPWy+TF1zM=
timeout: ${taoyao.timeout}
queue-size: 100000
min-thread: 4

View File

@@ -39,7 +39,7 @@ public class SocketClient extends ClientAdapter<AsynchronousSocketChannel> {
public SocketClient(SocketProperties socketProperties, AsynchronousSocketChannel instance) {
super(socketProperties.getTimeout(), instance);
this.ip = this.clientIp(instance);
this.cipher = CipherUtils.buildCipher(Cipher.ENCRYPT_MODE, socketProperties.getEncrypt(), socketProperties.getEncryptKey());
this.cipher = CipherUtils.buildCipher(Cipher.ENCRYPT_MODE, socketProperties.getEncrypt(), socketProperties.getEncryptSecret());
}
@Override

View File

@@ -66,7 +66,7 @@ public final class SocketSignalMessageHandler implements CompletionHandler<Integ
this.messageLength = 0;
this.bufferSize = socketProperties.getBufferSize();
this.maxBufferSize = socketProperties.getMaxBufferSize();
this.cipher = CipherUtils.buildCipher(Cipher.DECRYPT_MODE, socketProperties.getEncrypt(), socketProperties.getEncryptKey());
this.cipher = CipherUtils.buildCipher(Cipher.DECRYPT_MODE, socketProperties.getEncrypt(), socketProperties.getEncryptSecret());
this.buffer = ByteBuffer.allocateDirect(maxBufferSize);
this.channel = channel;
this.clientManager = clientManager;

View File

@@ -58,25 +58,25 @@ public class SocketSignalAutoConfiguration {
*/
private void buildSecret(SocketProperties socketProperties) {
log.info("Socket信令加密策略{}", socketProperties.getEncrypt());
if(socketProperties.getEncrypt() == null || StringUtils.isNotEmpty(socketProperties.getEncryptKey())) {
if(socketProperties.getEncrypt() == null) {
return;
}
if(StringUtils.isNotEmpty(socketProperties.getEncryptSecret())) {
log.info("Socket信令加密密码固定{}", socketProperties.getEncryptSecret());
return;
}
final byte[] bytes = switch (socketProperties.getEncrypt()) {
case AES -> new byte[16];
case DES -> new byte[8];
default -> null;
};
if(bytes == null) {
final Random random = new Random();
switch (socketProperties.getEncrypt()) {
case AES -> {
final byte[] bytes = new byte[16];
random.nextBytes(bytes);
socketProperties.setEncryptKey(Base64.getMimeEncoder().encodeToString(bytes));
random.nextBytes(bytes);
socketProperties.setEncryptSecret(Base64.getMimeEncoder().encodeToString(bytes));
log.info("Socket信令加密密码随机{}", socketProperties.getEncryptSecret());
} else {
log.warn("Socket信令加密密码算法不支持的算法{}", socketProperties.getEncrypt());
case DES -> {
final byte[] bytes = new byte[8];
random.nextBytes(bytes);
socketProperties.setEncryptKey(Base64.getMimeEncoder().encodeToString(bytes));
}
default -> {
// 其他情况使用明文
}
}
}
}

View File

@@ -0,0 +1,5 @@
package com.acgist.taoyao.signal.party.p2p;
public class Session {
}

View File

@@ -0,0 +1,5 @@
package com.acgist.taoyao.signal.party.p2p;
public class SessionManager {
}

View File

@@ -0,0 +1,5 @@
package com.acgist.taoyao.signal.protocol.p2p;
public class P2PAnswerProtocol {
}

View File

@@ -0,0 +1,5 @@
package com.acgist.taoyao.signal.protocol.p2p;
public class P2PCallProtocol {
}

View File

@@ -0,0 +1,5 @@
package com.acgist.taoyao.signal.protocol.p2p;
public class P2PCandidateProtocol {
}

View File

@@ -0,0 +1,5 @@
package com.acgist.taoyao.signal.protocol.p2p;
public class P2POfferProtocol {
}

View File

@@ -28,22 +28,22 @@ public class CipherUtils {
/**
* @param mode 模式
* @param encrypt 算法
* @param key 密钥
* @param secret 密钥
*
* @return 加密工具
*/
public static final Cipher buildCipher(int mode, Encrypt encrypt, String key) {
if(encrypt == null || encrypt == Encrypt.PLAINTEXT || StringUtils.isEmpty(key)) {
public static final Cipher buildCipher(int mode, Encrypt encrypt, String secret) {
if(encrypt == null || encrypt == Encrypt.PLAINTEXT || StringUtils.isEmpty(secret)) {
return null;
}
try {
final String algo = encrypt.getAlgo();
final String name = encrypt.name();
final Cipher cipher = Cipher.getInstance(algo);
cipher.init(mode, new SecretKeySpec(Base64.getMimeDecoder().decode(key), name));
cipher.init(mode, new SecretKeySpec(Base64.getMimeDecoder().decode(secret), name));
return cipher;
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e) {
log.error("创建加密工具异常:{} - {} - {}", mode, encrypt, key, e);
log.error("创建加密工具异常:{} - {} - {}", mode, encrypt, secret, e);
}
return null;
}