/// <summary> /// Final step client side. /// </summary> /// <param name="serverFrame"></param> /// <param name="clientName"></param> /// <returns></returns> public HandshakeFrame ClientConfirmExtensions(HandshakeFrame serverFrame, string clientName) { var extensions = _registry.GetRequiredForHandshake().ToList(); var required = new List<HandshakeExtension>(extensions); foreach (var extension in serverFrame.RequiredExtensions) { if (!extensions.Contains(extension)) extensions.Add(extension); if (!required.Contains(extension)) required.Add(extension); } //do not use optional extensions. // currently only use them to expose all extensions to the remote end point. //foreach (var extension in _registry.GetOptionalForHandshake()) //{ // if (!extensions.Contains(extension)) // extensions.Add(extension); //} //foreach (var extension in serverFrame.OptionalExtensions) //{ // if (!extensions.Contains(extension) && _registry.Exists(extension.Name)) // extensions.Add(extension); //} //var optional = _registry.GetOptionalForHandshake().Union(serverFrame.OptionalExtensions).Distinct(); _chosenExtensions = _registry.GetAll(extensions.Select(x => x.Name)); var negotiatedRequired = new List<HandshakeExtension>(); foreach (var handshakeExtension in required) { var serverExtension = serverFrame.RequiredExtensions.FirstOrDefault(x => x.IsSameExtension(handshakeExtension)); var clientExtension = _registry.Get(handshakeExtension.Name); var extension = clientExtension.Negotiate(serverExtension); negotiatedRequired.Add(extension); } return new HandshakeFrame { Identity = clientName, VersionMajor = SharpMessagingServer.Major, VersionMinor = SharpMessagingServer.Minor, OptionalExtensions = new HandshakeExtension[0], RequiredExtensions = required.ToArray() }; }
/// <summary> /// First step at server side /// </summary> /// <param name="clientFrame"></param> /// <param name="serverName"></param> /// <returns></returns> public IFrame ServerNegotiate(HandshakeFrame clientFrame, string serverName) { var ourRequired = _registry.GetRequiredForHandshake(); var missingExtensionsThatTheClientRequire = clientFrame.RequiredExtensions.Except(_registry.GetAllForHandshake(), new ExtensionNameComparer()) .ToList(); if (missingExtensionsThatTheClientRequire.Any()) { return new ErrorFrame("Server to not support the following extensions: " + string.Join(", ", missingExtensionsThatTheClientRequire)); } var missingExtensionsThatTheServerRequire = ourRequired.Except(clientFrame.RequiredExtensions.Union(clientFrame.OptionalExtensions), new ExtensionNameComparer()).ToList(); if (missingExtensionsThatTheServerRequire.Any()) { return new ErrorFrame("Server requires the following extensions: " + string.Join(", ", missingExtensionsThatTheServerRequire)); } var required = ourRequired.Union(clientFrame.RequiredExtensions).Distinct().ToList(); var chosenOptional = _registry.GetOptionalForHandshake() .Union(clientFrame.OptionalExtensions) .Distinct() .Except(required, new ExtensionNameComparer()); return new HandshakeFrame { Identity = serverName, VersionMajor = SharpMessagingServer.Major, VersionMinor = SharpMessagingServer.Minor, OptionalExtensions = chosenOptional.ToArray(), RequiredExtensions = required.ToArray() }; }
/// <summary> /// Final step at server side. /// </summary> /// <param name="clientFrame">Extensions that the client selected for this connection.</param> public void ServerConfirm(HandshakeFrame clientFrame) { var all = clientFrame.RequiredExtensions.Union(clientFrame.OptionalExtensions) .Distinct() .Select(x => x.Name); _chosenExtensions = _registry.GetAll(all); }