mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-25 03:05:20 +00:00
Share GossipSyncManager across transports to prevent redundant message synchronization
- Registered BluetoothMeshService's GossipSyncManager as a singleton in MeshServiceHolder. - Modified WifiAwareMeshService to use the shared GossipSyncManager if available. - Added background cleanup for peer mappings on socket disconnection. - Fixed Kotlin type mismatch during nickname map merging.
This commit is contained in:
@@ -94,6 +94,9 @@ class BluetoothMeshService(private val context: Context) {
|
|||||||
} catch (_: Exception) { 0.01 }
|
} catch (_: Exception) { 0.01 }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Register as shared instance for Wi-Fi Aware transport
|
||||||
|
com.bitchat.android.service.MeshServiceHolder.setGossipManager(gossipSyncManager)
|
||||||
|
|
||||||
// Wire sync manager delegate
|
// Wire sync manager delegate
|
||||||
gossipSyncManager.delegate = object : GossipSyncManager.Delegate {
|
gossipSyncManager.delegate = object : GossipSyncManager.Delegate {
|
||||||
|
|||||||
@@ -9,6 +9,12 @@ import com.bitchat.android.mesh.BluetoothMeshService
|
|||||||
*/
|
*/
|
||||||
object MeshServiceHolder {
|
object MeshServiceHolder {
|
||||||
private const val TAG = "MeshServiceHolder"
|
private const val TAG = "MeshServiceHolder"
|
||||||
|
@Volatile
|
||||||
|
var sharedGossipSyncManager: com.bitchat.android.sync.GossipSyncManager? = null
|
||||||
|
private set
|
||||||
|
|
||||||
|
fun setGossipManager(mgr: com.bitchat.android.sync.GossipSyncManager) { sharedGossipSyncManager = mgr }
|
||||||
|
|
||||||
@Volatile
|
@Volatile
|
||||||
var meshService: BluetoothMeshService? = null
|
var meshService: BluetoothMeshService? = null
|
||||||
private set
|
private set
|
||||||
|
|||||||
@@ -654,8 +654,8 @@ class ChatViewModel(
|
|||||||
|
|
||||||
// Merge nicknames from BLE and Wi‑Fi Aware to display names for all peers
|
// Merge nicknames from BLE and Wi‑Fi Aware to display names for all peers
|
||||||
val bleNick = meshService.getPeerNicknames()
|
val bleNick = meshService.getPeerNicknames()
|
||||||
val awareNick = try { com.bitchat.android.wifiaware.WifiAwareController.getService()?.getPeerNicknamesMap() } catch (_: Exception) { null }
|
val awareNickRaw = try { com.bitchat.android.wifiaware.WifiAwareController.getService()?.getPeerNicknamesMap() } catch (_: Exception) { null }
|
||||||
val mergedNick = if (awareNick != null) bleNick + awareNick.filterKeys { it !in bleNick || bleNick[it].isNullOrBlank() } else bleNick
|
val mergedNick = if (awareNickRaw != null) bleNick + awareNickRaw.filter { it.value != null }.mapValues { it.value!! }.filterKeys { it !in bleNick || bleNick[it].isNullOrBlank() } else bleNick
|
||||||
state.setPeerNicknames(mergedNick)
|
state.setPeerNicknames(mergedNick)
|
||||||
|
|
||||||
val rssiValues = meshService.getPeerRSSI()
|
val rssiValues = meshService.getPeerRSSI()
|
||||||
|
|||||||
@@ -106,24 +106,30 @@ class WifiAwareMeshService(private val context: Context) {
|
|||||||
setupDelegates()
|
setupDelegates()
|
||||||
messageHandler.packetProcessor = packetProcessor
|
messageHandler.packetProcessor = packetProcessor
|
||||||
|
|
||||||
gossipSyncManager = GossipSyncManager(
|
// Use shared GossipSyncManager from MeshServiceHolder if available (minimal refactor)
|
||||||
myPeerID = myPeerID,
|
val shared = com.bitchat.android.service.MeshServiceHolder.sharedGossipSyncManager
|
||||||
scope = serviceScope,
|
if (shared != null) {
|
||||||
configProvider = object : GossipSyncManager.ConfigProvider {
|
gossipSyncManager = shared
|
||||||
override fun seenCapacity(): Int = 500
|
} else {
|
||||||
override fun gcsMaxBytes(): Int = 400
|
gossipSyncManager = GossipSyncManager(
|
||||||
override fun gcsTargetFpr(): Double = 0.01
|
myPeerID = myPeerID,
|
||||||
}
|
scope = serviceScope,
|
||||||
)
|
configProvider = object : GossipSyncManager.ConfigProvider {
|
||||||
gossipSyncManager.delegate = object : GossipSyncManager.Delegate {
|
override fun seenCapacity(): Int = 500
|
||||||
override fun sendPacketToPeer(peerID: String, packet: BitchatPacket) {
|
override fun gcsMaxBytes(): Int = 400
|
||||||
this@WifiAwareMeshService.sendPacketToPeer(peerID, packet)
|
override fun gcsTargetFpr(): Double = 0.01
|
||||||
}
|
}
|
||||||
override fun sendPacket(packet: BitchatPacket) {
|
)
|
||||||
broadcastPacket(RoutedPacket(packet))
|
gossipSyncManager.delegate = object : GossipSyncManager.Delegate {
|
||||||
}
|
override fun sendPacketToPeer(peerID: String, packet: BitchatPacket) {
|
||||||
override fun signPacketForBroadcast(packet: BitchatPacket): BitchatPacket {
|
this@WifiAwareMeshService.sendPacketToPeer(peerID, packet)
|
||||||
return signPacketBeforeBroadcast(packet)
|
}
|
||||||
|
override fun sendPacket(packet: BitchatPacket) {
|
||||||
|
broadcastPacket(RoutedPacket(packet))
|
||||||
|
}
|
||||||
|
override fun signPacketForBroadcast(packet: BitchatPacket): BitchatPacket {
|
||||||
|
return signPacketBeforeBroadcast(packet)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -619,7 +625,7 @@ class WifiAwareMeshService(private val context: Context) {
|
|||||||
}
|
}
|
||||||
override fun onLost(network: Network) {
|
override fun onLost(network: Network) {
|
||||||
networkCallbacks.remove(peerId)
|
networkCallbacks.remove(peerId)
|
||||||
Log.d(TAG, "SERVER: network lost for ${peerId.take(8)}…")
|
Log.d(TAG, "SERVER: network lost for \${peerId.take(8)}…")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -826,15 +832,21 @@ class WifiAwareMeshService(private val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (routedPeerId == null) {
|
if (routedPeerId == null) {
|
||||||
|
routedPeerId = senderPeerHex
|
||||||
|
peerSockets[routedPeerId] = socket
|
||||||
|
}
|
||||||
|
|
||||||
Log.d(TAG, "RX: packet type=${pkt.type} from ${senderPeerHex.take(8)}… (bytes=${raw.size})")
|
Log.d(TAG, "RX: packet type=${pkt.type} from ${senderPeerHex.take(8)}… (bytes=${raw.size})")
|
||||||
packetProcessor.processPacket(RoutedPacket(pkt, routedPeerId))
|
packetProcessor.processPacket(RoutedPacket(pkt, routedPeerId))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop break -> disconnection
|
|
||||||
handlePeerDisconnection(initialLogicalPeerId, routedPeerId)
|
handlePeerDisconnection(initialLogicalPeerId, routedPeerId)
|
||||||
socket.closeQuietly()
|
socket.closeQuietly()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal helper to ensure peer is cleaned up from all managers when a socket dies.
|
||||||
|
*/
|
||||||
private fun handlePeerDisconnection(initialId: String, routedId: String?) {
|
private fun handlePeerDisconnection(initialId: String, routedId: String?) {
|
||||||
serviceScope.launch {
|
serviceScope.launch {
|
||||||
Log.w(TAG, "Cleaning up peer: $initialId / $routedId")
|
Log.w(TAG, "Cleaning up peer: $initialId / $routedId")
|
||||||
|
|||||||
Reference in New Issue
Block a user