//CLR has some method numbers encoding MemberInfo.MetadataToken. //It works only if assembly was build with the same version on the same machine. //And fails if 2 assemblies of the same version with the same code contract is built on different machines. //Will get different numbers on each side of communicated processes. Calls and callbacks will fail. Not used as identifier. private static int createIdentifier(MethodInfo info, int orderNumber) { int identifier = DEFAULT_ID_SHIFT + orderNumber; var dispatchId = AttributesReader.GetCustomAttribute <DispIdAttribute>(info); if (dispatchId != null) { identifier = dispatchId.Value; } return(identifier); }
private void Reflect(object service) { var serviceBehaviour = AttributesReader.GetServiceBehavior(service); if (serviceBehaviour != null) { _behaviour = serviceBehaviour; } if (service == null) { throw new ArgumentNullException("service"); } _service = service; _concurrency = _behaviour.ConcurrencyMode; }
private static OperationDispatchBase create(MethodInfo info, int identifier) { //BUG: fix not null async params //BUG: add all async patterns //BUG: fix WCF ref params var operation = AttributesReader.GetOperationContract(info); if (!operation.AsyncPattern) { return(new OperationDispatch(operation, info, identifier)); } else { return(new AsyncOperationDispatch(operation, info, identifier)); } }
private void Open(Type typeOfService, string serverAddress, Binding binding, string session, SynchronizationContext syncContext) { this.SynchronizationContext = syncContext; _typeOfService = typeOfService; _serverAddress = serverAddress; _binding = binding; _session = session; var contract = AttributesReader.GetServiceContract(_typeOfService); Debug.Assert(contract.CallbackContract != null); //BUG: should be used only for non polling HTTM, all others should go via provided single channel var address = _serverAddress + _session.Replace("-", ""); _callbackServer = new CallbackServiceHost(this, address, _behaviour); _callbackServer.AddServiceEndpoint(contract.CallbackContract, new Guid(_session), _binding, address); _callbackServer.Open(); }
//TODO: split RpcProxyRouter and RpcCallbackProxy public ClientRuntime(string address, ServiceEndpoint endpoint, bool callback = false, InstanceContext context = null, Guid customUuid = default(Guid), Type generatedProxyType = null) { _endpoint = endpoint; _binding = endpoint._binding; _serializer = _binding.Serializer; _typeOfService = endpoint._contractType; _context = context; if (_context != null && _context._useSynchronizationContext) { _syncContext = SynchronizationContext.Current; } _generatedProxyType = generatedProxyType; _address = address; _operations = DispatchTableFactory.GetOperations(_typeOfService); _uuid = EndpointMapper.CreateUuid(_address, _typeOfService); if (customUuid != Guid.Empty) // callback proxy { _uuid = customUuid; } var serviceContract = AttributesReader.GetServiceContract(_typeOfService); //TODO: null check only for duplex callback, really should always be here if (serviceContract != null && serviceContract.SessionMode == SessionMode.Required) { _session = Guid.NewGuid().ToString(); } //TODO: allow to be initialized with pregenerated proxy var realProxy = new RpcRealProxy(_typeOfService, this, _endpoint, _encoder); _remote = realProxy.GetTransparentProxy(); _client = RpcRequestReplyChannelFactory.CreateClient(_binding, _uuid, _address); foreach (var behavior in _endpoint.Behaviors) { behavior.ApplyClientBehavior(_endpoint, this); } }
public ServiceEndpoint AddServiceEndpoint(Type contractType, Binding binding, string address) { var uri = new Uri(address, UriKind.RelativeOrAbsolute); if (!uri.IsAbsoluteUri) { address = _baseAddress + address; } var uuid = EndpointMapper.CreateUuid(address, contractType); bool expectDuplexInitialization = false; var service = AttributesReader.GetServiceContract(contractType); if (service.CallbackContract != null) { expectDuplexInitialization = true; } RpcTrace.TraceEvent(TraceEventType.Start, "Start adding service endpoint for {0} at {1}", contractType, address); var endpoint = base.CreateEndpoint(contractType, binding, address, uuid); _endpointDispatchers.Add(new RpcEndpointDispatcher(_service, endpoint, expectDuplexInitialization)); return(endpoint); }
private OperationContext SetupOperationConext(IRpcCallInfo call, MessageRequest request, Type contractType) { var operationContext = new OperationContext { SessionId = request.Session }; if (request.Session != null) { if (_duplex) { lock (_clients) { RpcCallbackChannelFactory channelFactory = null; bool contains = _clients.TryGetValue(request.Session, out channelFactory); if (!contains) { var contract = AttributesReader.GetServiceContract(contractType); channelFactory = new RpcCallbackChannelFactory(_endpoint._binding, contract.CallbackContract, new Guid(request.Session), true); _clients[request.Session] = channelFactory; } var callbackBindingInfo = EndpointMapper.WcfToRpc(_endpoint._address); if (!call.IsClientLocal) { //BUG: callbacks accross network does not work //callbackAddress.NetworkAddr = call.ClientAddress } callbackBindingInfo.EndPoint += request.Session.Replace("-", ""); operationContext.SetGetter(_clients[request.Session], EndpointMapper.RpcToWcf(callbackBindingInfo)); } } } return(operationContext); }
public InstanceContext(object contextObject) { _contextObject = contextObject; _behaviour = AttributesReader.GetCallbackBehavior(contextObject.GetType()) ?? new CallbackBehaviorAttribute(); _useSynchronizationContext = _behaviour.UseSynchronizationContext; }