【m】优化socket代码
This commit is contained in:
@@ -94,6 +94,12 @@ namespace Unity.RenderStreaming.Signaling
|
||||
public event OnOfferHandler OnOffer;
|
||||
public event OnAnswerHandler OnAnswer;
|
||||
public event OnIceCandidateHandler OnIceCandidate;
|
||||
#pragma warning disable 0067
|
||||
public event OnParticipantJoinedHandler OnParticipantJoined;
|
||||
public event OnParticipantLeftHandler OnParticipantLeft;
|
||||
public event OnCallRequestHandler OnCallRequest;
|
||||
public event OnMessageHandler OnMessage;
|
||||
#pragma warning restore 0067
|
||||
|
||||
public void SendOffer(string connectionId, RTCSessionDescription offer)
|
||||
{
|
||||
|
||||
@@ -8,6 +8,10 @@ namespace Unity.RenderStreaming.Signaling
|
||||
public delegate void OnOfferHandler(ISignaling signaling, DescData e);
|
||||
public delegate void OnAnswerHandler(ISignaling signaling, DescData e);
|
||||
public delegate void OnIceCandidateHandler(ISignaling signaling, CandidateData e);
|
||||
public delegate void OnParticipantJoinedHandler(ISignaling signaling, ParticipantEventData e);
|
||||
public delegate void OnParticipantLeftHandler(ISignaling signaling, ParticipantEventData e);
|
||||
public delegate void OnCallRequestHandler(ISignaling signaling, CallRequestData e);
|
||||
public delegate void OnMessageHandler(ISignaling signaling, OnMessageData e);
|
||||
|
||||
public interface ISignaling
|
||||
{
|
||||
@@ -20,6 +24,10 @@ namespace Unity.RenderStreaming.Signaling
|
||||
event OnOfferHandler OnOffer;
|
||||
event OnAnswerHandler OnAnswer;
|
||||
event OnIceCandidateHandler OnIceCandidate;
|
||||
event OnParticipantJoinedHandler OnParticipantJoined;
|
||||
event OnParticipantLeftHandler OnParticipantLeft;
|
||||
event OnCallRequestHandler OnCallRequest;
|
||||
event OnMessageHandler OnMessage;
|
||||
|
||||
string Url { get; }
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Unity.RenderStreaming
|
||||
public string sdp;
|
||||
public bool polite;
|
||||
public DateTime dateTime;
|
||||
public string participantId;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
@@ -36,6 +37,9 @@ namespace Unity.RenderStreaming
|
||||
public string candidate;
|
||||
public string sdpMid;
|
||||
public int sdpMLineIndex;
|
||||
public string role;
|
||||
public string reason;
|
||||
public string data;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
@@ -106,5 +110,36 @@ namespace Unity.RenderStreaming
|
||||
public string datetime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 参与者加入/离开事件数据
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ParticipantEventData
|
||||
{
|
||||
public string connectionId;
|
||||
public string participantId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 呼叫请求数据
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class CallRequestData
|
||||
{
|
||||
public string connectionId;
|
||||
public string data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自定义消息数据
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class OnMessageData
|
||||
{
|
||||
public string connectionId;
|
||||
public string participantId;
|
||||
public string message;
|
||||
}
|
||||
|
||||
#pragma warning restore 0649
|
||||
}
|
||||
|
||||
@@ -24,6 +24,23 @@ namespace Unity.RenderStreaming.Signaling
|
||||
public string participantId;
|
||||
public string Url { get { return m_url; } }
|
||||
|
||||
/// <summary>
|
||||
/// 当前客户端是否为Host角色(由服务器在connect响应中分配)
|
||||
/// </summary>
|
||||
public bool isHost { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Host连接时使用的房间connectionId
|
||||
/// </summary>
|
||||
private string m_roomConnectionId;
|
||||
|
||||
/// <summary>
|
||||
/// 参与者连接ID到房间connectionId的映射
|
||||
/// Key: participantId, Value: roomConnectionId
|
||||
/// 用于Host向特定Participant发送消息时,将内部connectionId还原为服务器格式
|
||||
/// </summary>
|
||||
private Dictionary<string, string> m_participantToRoom = new Dictionary<string, string>();
|
||||
|
||||
public WebSocketSignaling(SignalingSettings signalingSettings, SynchronizationContext mainThreadContext)
|
||||
{
|
||||
if (signalingSettings == null)
|
||||
@@ -89,46 +106,97 @@ namespace Unity.RenderStreaming.Signaling
|
||||
public event OnAnswerHandler OnAnswer;
|
||||
#pragma warning restore 0067
|
||||
public event OnIceCandidateHandler OnIceCandidate;
|
||||
public event OnParticipantJoinedHandler OnParticipantJoined;
|
||||
public event OnParticipantLeftHandler OnParticipantLeft;
|
||||
public event OnCallRequestHandler OnCallRequest;
|
||||
public event OnMessageHandler OnMessage;
|
||||
|
||||
/// <summary>
|
||||
/// 判断一个connectionId是否为参与者连接ID(而非房间connectionId)
|
||||
/// </summary>
|
||||
private bool IsParticipantConnectionId(string connectionId)
|
||||
{
|
||||
return m_participantToRoom.ContainsKey(connectionId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取参与者对应的房间connectionId
|
||||
/// </summary>
|
||||
private string GetRoomConnectionId(string participantConnectionId)
|
||||
{
|
||||
return m_participantToRoom.TryGetValue(participantConnectionId, out var roomId) ? roomId : participantConnectionId;
|
||||
}
|
||||
|
||||
public void SendOffer(string connectionId, RTCSessionDescription offer)
|
||||
{
|
||||
DescData data = new DescData();
|
||||
data.connectionId = connectionId;
|
||||
// data.connectionId必须使用房间connectionId(服务器用此查找连接组进行路由)
|
||||
// 而不是内部participantId(participantId仅通过routedMessage.participantId传递用于目标选择)
|
||||
data.connectionId = IsParticipantConnectionId(connectionId) ? GetRoomConnectionId(connectionId) : connectionId;
|
||||
data.sdp = offer.sdp;
|
||||
data.dateTime = DateTime.Now;
|
||||
|
||||
RoutedMessage<DescData> routedMessage = new RoutedMessage<DescData>();
|
||||
routedMessage.from = connectionId;
|
||||
// 如果connectionId是参与者ID,使用房间connectionId作为from,并设置目标participantId
|
||||
if (IsParticipantConnectionId(connectionId))
|
||||
{
|
||||
routedMessage.from = GetRoomConnectionId(connectionId);
|
||||
routedMessage.participantId = connectionId;
|
||||
}
|
||||
else
|
||||
{
|
||||
routedMessage.from = connectionId;
|
||||
routedMessage.participantId = participantId;
|
||||
}
|
||||
routedMessage.data = data;
|
||||
routedMessage.type = "offer";
|
||||
routedMessage.participantId =participantId;
|
||||
WSSend(routedMessage);
|
||||
}
|
||||
|
||||
public void SendAnswer(string connectionId, RTCSessionDescription answer)
|
||||
{
|
||||
DescData data = new DescData();
|
||||
data.connectionId = connectionId;
|
||||
// data.connectionId必须使用房间connectionId(服务器用此查找连接组进行路由)
|
||||
data.connectionId = IsParticipantConnectionId(connectionId) ? GetRoomConnectionId(connectionId) : connectionId;
|
||||
data.sdp = answer.sdp;
|
||||
|
||||
RoutedMessage<DescData> routedMessage = new RoutedMessage<DescData>();
|
||||
routedMessage.from = connectionId;
|
||||
// 如果connectionId是参与者ID,使用房间connectionId作为from,并设置目标participantId
|
||||
if (IsParticipantConnectionId(connectionId))
|
||||
{
|
||||
routedMessage.from = GetRoomConnectionId(connectionId);
|
||||
routedMessage.participantId = connectionId;
|
||||
}
|
||||
else
|
||||
{
|
||||
routedMessage.from = connectionId;
|
||||
routedMessage.participantId = participantId;
|
||||
}
|
||||
routedMessage.data = data;
|
||||
routedMessage.type = "answer";
|
||||
routedMessage.participantId =participantId;
|
||||
WSSend(routedMessage);
|
||||
}
|
||||
|
||||
public void SendCandidate(string connectionId, RTCIceCandidate candidate)
|
||||
{
|
||||
CandidateData data = new CandidateData();
|
||||
data.connectionId = connectionId;
|
||||
// data.connectionId必须使用房间connectionId(服务器用此查找连接组进行路由)
|
||||
data.connectionId = IsParticipantConnectionId(connectionId) ? GetRoomConnectionId(connectionId) : connectionId;
|
||||
data.candidate = candidate.Candidate;
|
||||
data.sdpMLineIndex = candidate.SdpMLineIndex.GetValueOrDefault(0);
|
||||
data.sdpMid = candidate.SdpMid;
|
||||
|
||||
RoutedMessage<CandidateData> routedMessage = new RoutedMessage<CandidateData>();
|
||||
routedMessage.from = connectionId;
|
||||
// 如果connectionId是参与者ID,使用房间connectionId作为from,并设置目标participantId
|
||||
if (IsParticipantConnectionId(connectionId))
|
||||
{
|
||||
routedMessage.from = GetRoomConnectionId(connectionId);
|
||||
routedMessage.participantId = connectionId;
|
||||
}
|
||||
else
|
||||
{
|
||||
routedMessage.from = connectionId;
|
||||
}
|
||||
routedMessage.data = data;
|
||||
routedMessage.type = "candidate";
|
||||
|
||||
@@ -137,12 +205,16 @@ namespace Unity.RenderStreaming.Signaling
|
||||
|
||||
public void OpenConnection(string connectionId)
|
||||
{
|
||||
m_roomConnectionId = connectionId;
|
||||
this.WSSend($"{{\"type\":\"connect\", \"connectionId\":\"{connectionId}\"}}");
|
||||
}
|
||||
|
||||
public void CloseConnection(string connectionId)
|
||||
{
|
||||
this.WSSend($"{{\"type\":\"disconnect\", \"connectionId\":\"{connectionId}\"}}");
|
||||
// 如果关闭的是参与者连接,使用房间connectionId发送disconnect
|
||||
string actualConnectionId = IsParticipantConnectionId(connectionId) ? GetRoomConnectionId(connectionId) : connectionId;
|
||||
m_participantToRoom.Remove(connectionId);
|
||||
this.WSSend($"{{\"type\":\"disconnect\", \"connectionId\":\"{actualConnectionId}\"}}");
|
||||
}
|
||||
|
||||
private void WSManage()
|
||||
@@ -211,28 +283,51 @@ namespace Unity.RenderStreaming.Signaling
|
||||
if (routedMessage.type == "connect")
|
||||
{
|
||||
msg = JsonUtility.FromJson<SignalingMessage>(content);
|
||||
isHost = msg.role == "host";
|
||||
participantId = msg.participantId;
|
||||
m_mainThreadContext.Post(d => OnCreateConnection?.Invoke(this, msg.connectionId, msg.polite), null);
|
||||
participantId=msg.participantId;
|
||||
}
|
||||
else if (routedMessage.type == "disconnect")
|
||||
{
|
||||
msg = JsonUtility.FromJson<SignalingMessage>(content);
|
||||
m_mainThreadContext.Post(d => OnDestroyConnection?.Invoke(this, msg.connectionId), null);
|
||||
string disconnectConnectionId = msg.connectionId;
|
||||
// 如果断开的是参与者连接,用participantId查找内部connectionId
|
||||
if (!string.IsNullOrEmpty(routedMessage.participantId) && isHost)
|
||||
{
|
||||
disconnectConnectionId = routedMessage.participantId;
|
||||
m_participantToRoom.Remove(routedMessage.participantId);
|
||||
}
|
||||
m_mainThreadContext.Post(d => OnDestroyConnection?.Invoke(this, disconnectConnectionId), null);
|
||||
}
|
||||
else if (routedMessage.type == "offer")
|
||||
{
|
||||
DescData offer = new DescData();
|
||||
offer.connectionId = routedMessage.from;
|
||||
// Host收到带participantId的offer时,使用participantId作为内部connectionId
|
||||
// 这样每个participant会创建独立的PeerConnection
|
||||
if (!string.IsNullOrEmpty(routedMessage.participantId) && isHost)
|
||||
{
|
||||
offer.connectionId = routedMessage.participantId;
|
||||
m_participantToRoom[routedMessage.participantId] = routedMessage.from ?? m_roomConnectionId;
|
||||
}
|
||||
else
|
||||
{
|
||||
offer.connectionId = routedMessage.from;
|
||||
}
|
||||
offer.sdp = msg.sdp;
|
||||
offer.polite = msg.polite;
|
||||
offer.participantId = routedMessage.participantId;
|
||||
m_mainThreadContext.Post(d => OnOffer?.Invoke(this, offer), null);
|
||||
}
|
||||
else if (routedMessage.type == "answer")
|
||||
{
|
||||
DescData answer = new DescData
|
||||
{
|
||||
connectionId = routedMessage.from,
|
||||
sdp = msg.sdp
|
||||
// Host收到带participantId的answer时,使用participantId作为内部connectionId
|
||||
connectionId = !string.IsNullOrEmpty(routedMessage.participantId) && isHost
|
||||
? routedMessage.participantId
|
||||
: routedMessage.from,
|
||||
sdp = msg.sdp,
|
||||
participantId = routedMessage.participantId
|
||||
};
|
||||
m_mainThreadContext.Post(d => OnAnswer?.Invoke(this, answer), null);
|
||||
}
|
||||
@@ -240,13 +335,68 @@ namespace Unity.RenderStreaming.Signaling
|
||||
{
|
||||
CandidateData candidate = new CandidateData
|
||||
{
|
||||
connectionId = routedMessage.@from,
|
||||
// Host收到带participantId的candidate时,使用participantId作为内部connectionId
|
||||
connectionId = !string.IsNullOrEmpty(routedMessage.participantId) && isHost
|
||||
? routedMessage.participantId
|
||||
: routedMessage.@from,
|
||||
candidate = msg.candidate,
|
||||
sdpMLineIndex = msg.sdpMLineIndex,
|
||||
sdpMid = msg.sdpMid
|
||||
sdpMid = msg.sdpMid,
|
||||
participantId = routedMessage.participantId
|
||||
};
|
||||
m_mainThreadContext.Post(d => OnIceCandidate?.Invoke(this, candidate), null);
|
||||
}
|
||||
else if (routedMessage.type == "participant-joined")
|
||||
{
|
||||
// Host收到新参与者加入通知
|
||||
msg = JsonUtility.FromJson<SignalingMessage>(content);
|
||||
ParticipantEventData participantData = new ParticipantEventData
|
||||
{
|
||||
connectionId = msg.connectionId ?? routedMessage.from,
|
||||
participantId = msg.participantId ?? routedMessage.participantId
|
||||
};
|
||||
// 记录参与者映射
|
||||
if (!string.IsNullOrEmpty(participantData.participantId))
|
||||
{
|
||||
m_participantToRoom[participantData.participantId] = participantData.connectionId;
|
||||
}
|
||||
RenderStreaming.Logger.Log($"Signaling: Participant joined - connectionId: {participantData.connectionId}, participantId: {participantData.participantId}");
|
||||
m_mainThreadContext.Post(d => OnParticipantJoined?.Invoke(this, participantData), null);
|
||||
}
|
||||
else if (routedMessage.type == "participant-left")
|
||||
{
|
||||
// Host/Participant收到参与者离开通知
|
||||
msg = JsonUtility.FromJson<SignalingMessage>(content);
|
||||
ParticipantEventData participantData = new ParticipantEventData
|
||||
{
|
||||
connectionId = msg.connectionId ?? routedMessage.from,
|
||||
participantId = msg.participantId ?? routedMessage.participantId
|
||||
};
|
||||
m_participantToRoom.Remove(participantData.participantId);
|
||||
RenderStreaming.Logger.Log($"Signaling: Participant left - connectionId: {participantData.connectionId}, participantId: {participantData.participantId}");
|
||||
m_mainThreadContext.Post(d => OnParticipantLeft?.Invoke(this, participantData), null);
|
||||
}
|
||||
else if (routedMessage.type == "call-request")
|
||||
{
|
||||
msg = JsonUtility.FromJson<SignalingMessage>(content);
|
||||
CallRequestData callData = new CallRequestData
|
||||
{
|
||||
connectionId = routedMessage.from,
|
||||
data = msg.data
|
||||
};
|
||||
m_mainThreadContext.Post(d => OnCallRequest?.Invoke(this, callData), null);
|
||||
}
|
||||
else if (routedMessage.type == "on-message")
|
||||
{
|
||||
msg = JsonUtility.FromJson<SignalingMessage>(content);
|
||||
OnMessageData messageData = new OnMessageData
|
||||
{
|
||||
connectionId = routedMessage.from,
|
||||
participantId = routedMessage.participantId,
|
||||
message = msg.message
|
||||
};
|
||||
m_mainThreadContext.Post(d => OnMessage?.Invoke(this, messageData), null);
|
||||
}
|
||||
else if (routedMessage.type == "error")
|
||||
{
|
||||
msg = JsonUtility.FromJson<SignalingMessage>(content);
|
||||
|
||||
Reference in New Issue
Block a user