Пример #1
0
 /// <summary>
 /// Unsubscribe from all topics specified.
 /// </summary>
 public static void Unsubscribe(this IZmqSocket source, string[] topics)
 {
     foreach (var topic in topics)
     {
         source.Unsubscribe(topic);
     }
 }
Пример #2
0
		public void Return(IZmqSocket socket, string endpoint, bool inError)
		{
			if (socket == null) throw new ArgumentNullException("socket");
			if (string.IsNullOrEmpty(endpoint)) throw new ArgumentNullException("endpoint");

			var endpointPoll = _endpoint2Sockets.GetOrAdd(endpoint, _ => new EndpointPoll());

			if (_disposed || inError)
			{
//				if (endpointPoll.monitor != null && endpointPoll.monitor.Socket == socket)
//				{
//					endpointPoll.monitor.Dispose();
//					endpointPoll.monitored = false;
//				}

				socket.Dispose();
			}

			this.Untrack(socket);

			if (_disposed || inError)
			{
				return;
			}

			var socketQueue = endpointPoll.SocketsQueue;

			// make available to next one
			socketQueue.Enqueue(socket);

			// this may defeat the purpose of a poll (if it puts the SO socket in a time_wait state)
			// socket.Disconnect(endpoint);
		}
Пример #3
0
 private void Untrack(IZmqSocket socket)
 {
     lock (this._socketsInUse)
     {
         this._socketsInUse.Remove(socket);
     }
 }
Пример #4
0
        /// <summary>
        /// Sends the byte[] message and uses the specified flags to configure the sending behavior.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message">The byte array to send</param>
        /// <param name="flags">Send flags configuring the sending operation</param>
        public static void Send(this IZmqSocket source, byte[] message, SendFlags flags)
        {
            bool hasMore   = (flags & SendFlags.SendMore) != 0;
            bool doNotWait = (flags & SendFlags.DoNotWait) != 0;

            source.Send(message, hasMore, doNotWait);
        }
Пример #5
0
        protected override void SendRequest(IZmqSocket socket)
        {
            var buffer = _serializationStrategy.SerializeRequest(_requestMessage);

            socket.Send(buffer);
            // PerfCounters.IncrementSent()
        }
Пример #6
0
		public RemoteRequestListener2(IZmqContext context, string endpoint, int workers,
			LocalInvocationDispatcher dispatcher,
			SerializationStrategy serializationStrategy)
		{
			_endpoint = endpoint;
			_dispatcher = dispatcher;
			_serializationStrategy = serializationStrategy;
			_reply = context.Rep();
		}
Пример #7
0
        public static void SetOption(this IZmqSocket source, SocketOpt option, byte[] buffer)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }

            source.SetOption <byte[]>((int)option, buffer);
        }
Пример #8
0
        public static void SetOption(this IZmqSocket source, SocketOpt option, string value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            source.SetOption <string>((int)option, value);
        }
Пример #9
0
 public RemoteRequestListener2(IZmqContext context, string endpoint, int workers,
                               LocalInvocationDispatcher dispatcher,
                               SerializationStrategy serializationStrategy)
 {
     _endpoint              = endpoint;
     _dispatcher            = dispatcher;
     _serializationStrategy = serializationStrategy;
     _reply = context.Rep();
 }
Пример #10
0
		private void OnRequestReceived(byte[] message, IZmqSocket socket)
		{
			var reqMessage = _serializationStrategy.DeserializeRequest(message);

			ResponseMessage response = InternalDispatch(reqMessage);

			var buffer = _serializationStrategy.SerializeResponse(response);
			socket.Send(buffer);
		}
Пример #11
0
 internal CastleZmqSocket(CastleZmqSocketFactory factory, IZmqSocket socket)
 {
     if (socket == null)
     {
         throw new ArgumentNullException("socket");
     }
     _factory = factory;
     _socket  = socket;
     _factory.AddSocket(this);
 }
Пример #12
0
        private void OnRequestReceived(byte[] message, IZmqSocket socket)
        {
            var reqMessage = _serializationStrategy.DeserializeRequest(message);

            ResponseMessage response = InternalDispatch(reqMessage);

            var buffer = _serializationStrategy.SerializeResponse(response);

            socket.Send(buffer);
        }
Пример #13
0
        public static void Bind(this IZmqSocket source, Transport transport, string address, uint port, int timeout = Socket.InfiniteTimeout)
        {
            var endpoint = BuildEndpoint(transport, address, port);

            if (timeout != Socket.InfiniteTimeout)
            {
                source.SetOption(SocketOpt.RCVTIMEO, timeout);
            }

            source.Bind(endpoint);
        }
Пример #14
0
		protected Device(IZmqSocket frontend, IZmqSocket backend, bool enableCapture = false)
		{
			if (frontend == null) throw new ArgumentNullException("frontend");
			if (backend == null) throw new ArgumentNullException("backend");

			this.Frontend = frontend;
			this.Backend = backend;

			this._needsBinding = false;
			this._enableCapture = enableCapture;
		}
Пример #15
0
 public SharedQueue(IZmqSocket frontend, IZmqSocket backend, bool enableCapture = false) : base(frontend, backend, enableCapture)
 {
     if (frontend.SocketType != SocketType.Router)
     {
         throw new ArgumentException("Frontend must be a Router");
     }
     if (backend.SocketType != SocketType.Dealer)
     {
         throw new ArgumentException("Backend must be a Dealer");
     }
 }
Пример #16
0
 public Forwarder(IZmqSocket frontend, IZmqSocket backend, bool enableCapture = false)
     : base(frontend, backend, enableCapture)
 {
     if (frontend.SocketType != SocketType.XSub)
     {
         throw new ArgumentException("Frontend must be a XSub");
     }
     if (backend.SocketType != SocketType.XPub)
     {
         throw new ArgumentException("Backend must be a XPub");
     }
 }
Пример #17
0
        public static void Send(this IZmqSocket source, ArraySegment <byte> buffer, bool hasMoreToSend = false, bool noWait = false)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }

            var segment = new byte[buffer.Count];

            Buffer.BlockCopy(buffer.Array, buffer.Offset, segment, 0, segment.Length);

            source.Send(segment, hasMoreToSend, noWait);
        }
Пример #18
0
        protected override ResponseMessage GetReply(byte[] buffer, IZmqSocket socket, bool hasTimeoutWaitingRecv)
        {
            // var buffer = socket.Recv();

            if (hasTimeoutWaitingRecv)
            {
                var message = "Remote call took too long to respond. Is the server up? Endpoint: " +
                              _endpoint + " - Current timeout " + this.Timeout;
                return(new ResponseMessage(null, null, new ExceptionInfo(TimeoutTypename, message)));
            }

            return(_serializationStrategy.DeserializeResponse(buffer));
        }
Пример #19
0
        /// <summary>
        /// Sends a string message, converting to bytes using the
        /// encoding specified. If none, uses UTF8.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message">The string message</param>
        /// <param name="encoding">If not specified, defaults to UTF8</param>
        /// <param name="hasMoreToSend">Flag indicating whether it's a multipart message</param>
        /// <param name="noWait">Indicates that the sock must send the message immediately</param>
        public static void Send(this IZmqSocket source, string message, Encoding encoding = null,
                                bool hasMoreToSend = false, bool noWait = false)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            encoding = encoding ?? Encoding.UTF8;
            var buffer = encoding.GetBytes(message);

            source.Send(buffer, hasMoreToSend, noWait);
        }
Пример #20
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="source"></param>
        /// <param name="flags"></param>
        /// <param name="encoding">If not specified, defaults to UTF8</param>
        /// <returns></returns>
        public static string RecvString(this IZmqSocket source, RecvFlags flags, Encoding encoding = null)
        {
            var buffer = Recv(source, flags);

            if (buffer == null)
            {
                return(null);
            }

            encoding = encoding ?? Encoding.UTF8;

            return(encoding.GetString(buffer));
        }
Пример #21
0
        public void Init()
        {
            var initlogger = LogManager.GetLogger("common");

            _zmqCtx = new Context();

            foreach (var i in Utils.GetTypesWithServiceAttribute())
            {
                var attr    = i.GetCustomAttribute(typeof(MT4ServiceAttribute)) as MT4ServiceAttribute;
                var service = i;
                if (attr.EnableZMQ)
                {
                    var serviceName = string.Empty;
                    if (!string.IsNullOrWhiteSpace(attr.ZmqApiName))
                    {
                        serviceName = attr.ZmqApiName;
                    }
                    else
                    {
                        serviceName = service.Name;
                    }
                    initlogger.Info(string.Format("准备初始化ZMQ服务:{0}", serviceName));
                    _apiDict[serviceName]  = i;
                    _attrDict[serviceName] = attr;
                }
            }
            var pubSocket = _zmqCtx.CreateSocket(SocketType.Pub);

            _pubSocket = pubSocket;
            var proto_items = ZmqBindAddr.Split(':');
            var port_range  = proto_items[2].Split('-').Select
                                  (i => int.Parse(i.Trim())).ToArray();

            if (port_range[0] > port_range[1] || port_range[1] - port_range[0] > 100)
            {
                throw new Exception("端口范围设定有bug");
            }
            pubSocket.Bind(ZmqPubBindAddr);
            _publisher = pubSocket;
            var th_pub = new Thread(PubProc);

            th_pub.IsBackground = true;
            th_pub.Start();
            var lstSockets = new List <IZmqSocket>();

            for (int i = port_range[0]; i <= port_range[1]; i++)
            {
                var addr = string.Format("{0}:{1}:{2}", proto_items[0], proto_items[1], i);
                lstSockets.Add(StartLink(addr));
            }
        }
Пример #22
0
        public virtual void Start()
        {
            EnsureNotDisposed();

            if (this._socket == null)
            {
                this._socket = this._context.CreateSocket(SocketType.Pub);
            }
            if (!this._started)
            {
                this._socket.Bind(this._endpoint);
                this._started = true;
            }
        }
Пример #23
0
        public MonitoredSocket(IZmqContext context, IZmqSocket socket)
        {
            this._socket = socket;

            this._monitor              = new Castle.Zmq.Monitor(socket, context);
            this._monitor.SocketEvent += (sender, args) =>
            {
                switch (args.Event)
                {
                case MonitorEvents.BindFailed:
                case MonitorEvents.AcceptFailed:
                case MonitorEvents.CloseFailed:
                    if (!_inError)
                    {
                        _inError = true;
                        Thread.MemoryBarrier();

                        FireError(args);
                    }
                    break;

                case MonitorEvents.ConnectRetried:
                case MonitorEvents.Closed:
                case MonitorEvents.Disconnected:
                    if (!_disconnected)
                    {
                        _disconnected = true;
                        _connected    = false;
                        Thread.MemoryBarrier();

                        FireDisconnected(args);
                    }
                    break;

                case MonitorEvents.Connected:
                case MonitorEvents.Listening:
                    if (!_connected)
                    {
                        _connected = true;
                        _inError   = _disconnected = false;
                        Thread.MemoryBarrier();

                        FireConnected(args);
                    }
                    break;
                }
            };
        }
Пример #24
0
		public MonitoredSocket(IZmqContext context, IZmqSocket socket)
		{
			this._socket = socket;

			this._monitor = new Castle.Zmq.Monitor(socket, context);
			this._monitor.SocketEvent += (sender, args) =>
			{
				switch (args.Event)
				{
					case MonitorEvents.BindFailed:
					case MonitorEvents.AcceptFailed:
					case MonitorEvents.CloseFailed:
						if (!_inError)
						{
							_inError = true;
							Thread.MemoryBarrier();

							FireError(args);
						}
						break;
					case MonitorEvents.ConnectRetried:
					case MonitorEvents.Closed:
					case MonitorEvents.Disconnected:
						if (!_disconnected)
						{
							_disconnected = true;
							_connected = false;
							Thread.MemoryBarrier();

							FireDisconnected(args);
						}
						break;
					case MonitorEvents.Connected:
					case MonitorEvents.Listening:
						if (!_connected)
						{
							_connected = true;
							_inError = _disconnected = false;
							Thread.MemoryBarrier();

							FireConnected(args);
						}
						break;
				}
			};
		}
Пример #25
0
        protected Device(IZmqSocket frontend, IZmqSocket backend, bool enableCapture = false)
        {
            if (frontend == null)
            {
                throw new ArgumentNullException("frontend");
            }
            if (backend == null)
            {
                throw new ArgumentNullException("backend");
            }

            this.Frontend = frontend;
            this.Backend  = backend;

            this._needsBinding  = false;
            this._enableCapture = enableCapture;
        }
Пример #26
0
        public Monitor(IZmqSocket socket, IZmqContext context,
                       string monitorName   = null,
                       MonitorEvents events = MonitorEvents.All)
        {
            if (socket == null)
            {
                throw new ArgumentNullException("socket");
            }
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            if (monitorName != null)
            {
                if (!monitorName.StartsWith("inproc://"))
                {
                    monitorName = "inproc://" + monitorName;
                }
            }
            else
            {
                monitorName = "inproc://temp" + Rnd.Next(0, Int32.MaxValue);
            }

            this._monitorName = monitorName;

            // Creates a inproc socket pair
            var res = Native.Monitor.zmq_socket_monitor(socket.Handle(), monitorName, (int)events);

            if (res == Native.ErrorCode)
            {
                Native.ThrowZmqError("Monitor");
            }

            // Connects to the newly created socket pair
            this._pairSocket = context.Pair();
            this._pairSocket.Connect(this._monitorName);

            this._thread = new Thread(EventsWorker)
            {
                IsBackground = true
            };
            this._thread.Start();
        }
Пример #27
0
        private Tuple <T, bool> SendReqAndWaitReply(IZmqSocket socket)
        {
            SendRequest(socket);

            var polling = new Polling(PollingEvents.RecvReady, socket);

            if (polling.Poll(this.Timeout))
            {
                var data = socket.Recv();
                var ret  = GetReply(data, socket, false);
                return(Tuple.Create(ret, false));
            }
            else
            {
                // timeout
                var ret = GetReply(null, socket, true);
                return(Tuple.Create(ret, true));
            }
        }
Пример #28
0
        public virtual void Start()
        {
            EnsureNotDisposed();

            if (this._socket == null)
            {
                this._socket = this._context.CreateSocket(SocketType.Sub);
            }
            if (!this._started)
            {
                this._socket.Connect(this._endpoint);

                this._worker = new Thread(OnRecvWorker)
                {
                    IsBackground = true
                };
                this._started = true;
                this._worker.Start();
            }
        }
Пример #29
0
        public void Return(IZmqSocket socket, string endpoint, bool inError)
        {
            if (socket == null)
            {
                throw new ArgumentNullException("socket");
            }
            if (string.IsNullOrEmpty(endpoint))
            {
                throw new ArgumentNullException("endpoint");
            }

            var endpointPoll = _endpoint2Sockets.GetOrAdd(endpoint, _ => new EndpointPoll());

            if (_disposed || inError)
            {
//				if (endpointPoll.monitor != null && endpointPoll.monitor.Socket == socket)
//				{
//					endpointPoll.monitor.Dispose();
//					endpointPoll.monitored = false;
//				}

                socket.Dispose();
            }

            this.Untrack(socket);

            if (_disposed || inError)
            {
                return;
            }

            var socketQueue = endpointPoll.SocketsQueue;

            // make available to next one
            socketQueue.Enqueue(socket);

            // this may defeat the purpose of a poll (if it puts the SO socket in a time_wait state)
            // socket.Disconnect(endpoint);
        }
Пример #30
0
		public Monitor(IZmqSocket socket, IZmqContext context, 
					   string monitorName = null, 
					   MonitorEvents events = MonitorEvents.All)
		{
			if (socket == null) throw new ArgumentNullException("socket");
			if (context == null) throw new ArgumentNullException("context");

			if (monitorName != null)
			{
				if (!monitorName.StartsWith("inproc://"))
					monitorName = "inproc://" + monitorName;
			}
			else
			{
				monitorName = "inproc://temp" + Rnd.Next(0, Int32.MaxValue);
			}

			this._monitorName = monitorName;

			// Creates a inproc socket pair
			var res = Native.Monitor.zmq_socket_monitor(socket.Handle(), monitorName, (int)events);
			if (res == Native.ErrorCode)
			{
				Native.ThrowZmqError("Monitor");
			}

			// Connects to the newly created socket pair
			this._pairSocket = context.Pair();
			this._pairSocket.Connect(this._monitorName);

			this._thread = new Thread(EventsWorker)
			{
				IsBackground = true
			};
			this._thread.Start();
		}
Пример #31
0
		public virtual void Start()
		{
			EnsureNotDisposed();
			if (!this._ownSockets)
			{
				if (!(this.Frontend is Socket)) throw new InvalidOperationException("Frontend instance is not a Socket");
				if (!(this.Backend is Socket)) throw new InvalidOperationException("Backend instance is not a Socket");
			}

			var thread = new Thread(() =>
			{
				if (this._ownSockets)
				{
					this.Frontend = _ctx.CreateSocket(this._frontendType);
					this.Backend = _ctx.CreateSocket(this._backendType);
				}

				var front = (Socket)this.Frontend;
				var back = (Socket)this.Backend;

				StartFrontEnd();
				StartBackEnd();

				IZmqSocket capReceiver;
				IZmqSocket captureSink = capReceiver = null;

				if (this._enableCapture)
				{
					var rnd = new Random((int)DateTime.Now.Ticks);
					
					var captureendpoint = "inproc://capture" + rnd.Next(0, Int32.MaxValue);
					captureSink = _ctx.Pair();
					captureSink.Bind(captureendpoint);

					capReceiver = _ctx.Pair();
					capReceiver.Connect(captureendpoint);

					var captureThread = new Thread(() =>
					{
						try
						{
							while (true)
							{
								var data = capReceiver.Recv();
								if (data == null) continue;

								var ev = this.Captured;
								if (ev != null)
								{
									ev(data);
								}
							}
						}
						catch (Exception e)
						{
							if (LogAdapter.LogEnabled)
							{
								LogAdapter.LogError("DeviceCapture", e.ToString());
							}
						}
					})
					{
						IsBackground = true, 
						Name = "Capture thread for " + captureendpoint
					};
					captureThread.Start();
				}

				var captureHandle = _enableCapture ? captureSink.Handle() : IntPtr.Zero;

			restart:
				// this will block forever, hence it's running in a separate thread
				var res = Native.Device.zmq_proxy(front.Handle(), back.Handle(), captureHandle);
				if (res == Native.ErrorCode)
				{
					if (Native.LastError() == ZmqErrorCode.EINTR) // unix interruption
					{
						goto restart;
					}

					// force disposal since these sockets were eterm'ed or worse
					this.Dispose();

					if (captureSink != null) captureSink.Dispose();
					if (capReceiver != null) capReceiver.Dispose();

					// this is expected
					if (Native.LastError() == ZmqErrorCode.ETERM) return;
					
					// not expected
					var msg = "Error on zmq_proxy: " + Native.LastErrorString();
					System.Diagnostics.Trace.TraceError(msg);
					System.Diagnostics.Debug.WriteLine(msg);
					if (LogAdapter.LogEnabled)
					{
						LogAdapter.LogError(this.GetType().FullName, msg);
					}
				}
			})
			{
				IsBackground = true
			};
			thread.Start();
		}
Пример #32
0
		public SharedQueue(IZmqSocket frontend, IZmqSocket backend, bool enableCapture = false) : base(frontend, backend, enableCapture)
		{
			if (frontend.SocketType != SocketType.Router) throw new ArgumentException("Frontend must be a Router");
			if (backend.SocketType != SocketType.Dealer) throw new ArgumentException("Backend must be a Dealer");
		}
Пример #33
0
 /// <summary>
 /// Returns true if the last message received has indicated
 /// that there's more to come (part of a multipart message).
 /// Otherwise false.
 /// </summary>
 /// <param name="source"></param>
 /// <returns>true if last message was a multipart message</returns>
 public static bool HasMoreToRecv(this IZmqSocket source)
 {
     return(source.GetOption <bool>(SocketOpt.RCVMORE));
 }
Пример #34
0
        public static byte[] Recv(this IZmqSocket source, RecvFlags flags)
        {
            bool doNotWait = (flags & RecvFlags.DoNotWait) != 0;

            return(source.Recv(doNotWait));
        }
Пример #35
0
        public virtual void Start()
        {
            EnsureNotDisposed();
            if (!this._ownSockets)
            {
                if (!(this.Frontend is Socket))
                {
                    throw new InvalidOperationException("Frontend instance is not a Socket");
                }
                if (!(this.Backend is Socket))
                {
                    throw new InvalidOperationException("Backend instance is not a Socket");
                }
            }

            var thread = new Thread(() =>
            {
                if (this._ownSockets)
                {
                    this.Frontend = _ctx.CreateSocket(this._frontendType);
                    this.Backend  = _ctx.CreateSocket(this._backendType);
                }

                var front = (Socket)this.Frontend;
                var back  = (Socket)this.Backend;

                StartFrontEnd();
                StartBackEnd();

                IZmqSocket capReceiver;
                IZmqSocket captureSink = capReceiver = null;

                if (this._enableCapture)
                {
                    var rnd = new Random((int)DateTime.Now.Ticks);

                    var captureendpoint = "inproc://capture" + rnd.Next(0, Int32.MaxValue);
                    captureSink         = _ctx.Pair();
                    captureSink.Bind(captureendpoint);

                    capReceiver = _ctx.Pair();
                    capReceiver.Connect(captureendpoint);

                    var captureThread = new Thread(() =>
                    {
                        try
                        {
                            while (true)
                            {
                                var data = capReceiver.Recv();
                                if (data == null)
                                {
                                    continue;
                                }

                                var ev = this.Captured;
                                if (ev != null)
                                {
                                    ev(data);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            if (LogAdapter.LogEnabled)
                            {
                                LogAdapter.LogError("DeviceCapture", e.ToString());
                            }
                        }
                    })
                    {
                        IsBackground = true,
                        Name         = "Capture thread for " + captureendpoint
                    };
                    captureThread.Start();
                }

                var captureHandle = _enableCapture ? captureSink.Handle() : IntPtr.Zero;

                restart:
                // this will block forever, hence it's running in a separate thread
                var res = Native.Device.zmq_proxy(front.Handle(), back.Handle(), captureHandle);
                if (res == Native.ErrorCode)
                {
                    if (Native.LastError() == ZmqErrorCode.EINTR)                     // unix interruption
                    {
                        goto restart;
                    }

                    // force disposal since these sockets were eterm'ed or worse
                    this.Dispose();

                    if (captureSink != null)
                    {
                        captureSink.Dispose();
                    }
                    if (capReceiver != null)
                    {
                        capReceiver.Dispose();
                    }

                    // this is expected
                    if (Native.LastError() == ZmqErrorCode.ETERM)
                    {
                        return;
                    }

                    // not expected
                    var msg = "Error on zmq_proxy: " + Native.LastErrorString();
                    System.Diagnostics.Trace.TraceError(msg);
                    System.Diagnostics.Debug.WriteLine(msg);
                    if (LogAdapter.LogEnabled)
                    {
                        LogAdapter.LogError(this.GetType().FullName, msg);
                    }
                }
            })
            {
                IsBackground = true
            };

            thread.Start();
        }
Пример #36
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="source"></param>
 /// <param name="encoding">If not specified, defaults to UTF8</param>
 /// <returns></returns>
 public static string RecvString(this IZmqSocket source, Encoding encoding = null)
 {
     return(RecvString(source, RecvFlags.None, encoding));
 }
Пример #37
0
 internal CastleZmqSubSocket(CastleZmqSocketFactory factory, IZmqSocket socket) : base(factory, socket)
 {
 }
Пример #38
0
		private void Untrack(IZmqSocket socket)
		{
			lock (this._socketsInUse)
			{
				this._socketsInUse.Remove(socket);
			}
		}
Пример #39
0
 public CastleZmqSocket Wrap(IZmqSocket socket)
 {
     return(new CastleZmqSocket(this, socket));
 }
Пример #40
0
		public Forwarder(IZmqSocket frontend, IZmqSocket backend, bool enableCapture = false)
			: base(frontend, backend, enableCapture)
		{
			if (frontend.SocketType != SocketType.XSub) throw new ArgumentException("Frontend must be a XSub");
			if (backend.SocketType != SocketType.XPub) throw new ArgumentException("Backend must be a XPub");
		}