Код службы WCF не был вызван, если это IsOneWay = true
Я расширяю транспорт WCF по шине сообщений, мне хорошо подходит режим запрос-ответ. При реализации режима ввода-вывода я столкнулся с проблемой. Ситуация такова:
1, я создал InputChannel и OutputChannel и позволил TransportBindingElement возвращать их.
2, я создал контрактный интерфейс, который имеет два метода. Один из них имеет атрибут IsOneWay = true, скажем, это Method1; другой не был назван Method2.
3. Если я вызвал Method1, я вижу, что он дал мне RequestChannel и ReplyChannel вместо InputChannel и OutputChannel. И ответный канал может получить сообщение WCF и вернуть RequestContext обратно. Но сервисный код не был вызван.
4, если я установлю IsOneWay = false на Method1, это работает хорошо.
4, если я вызвал Method2, он работает хорошо.
5, я создал другой контракт на обслуживание, в котором есть только один метод с IsOneWay = true. Если я вызвал этот метод, WCF дал мне InputChannel и OutputChannel, и он работает хорошо (выполняется код службы).
Итак, мой вопрос: 1, если у меня есть служба с методами IsOneWay = true и методами IsOneWay = false, WCF предоставит мне канал запроса-ответа, это правильно?
2. Как я могу обработать сервисный вызов, метод которого был IsOneWay = true, но также имеет методы IsOneWay = false в том же сервисном контракте?
Кстати, я заметил, что для сообщений с запросом к методу IsOneWay = true, MessageID был НЕДЕЙСТВИТЕЛЕН. Я установил новый идентификатор в сообщении запроса, но не повезло, сервисный код все еще не вызывался.
2 ответа
Ну, я наконец-то получил причину и решение.
WCF выберет лучшую форму канала на основе всего контракта на обслуживание, а не на какую сервисную операцию вы вызвали. Поэтому, если у меня есть контракт на обслуживание с методами IsOneWay = true и IsOneWay = false, WCF будет использовать режим запроса-ответа, поскольку он может охватывать все возможные вызовы.
Затем, когда WCF использует режим запрос-ответ для обработки одностороннего сообщения, ответное сообщение будет нулевым. Это означает, что в методе RequestContext.Reply входящее сообщение от параметра равно нулю. Поэтому мы не можем обработать это, как в обычном режиме запрос-ответ (в этом режиме ответное сообщение не должно быть нулевым). Теперь нам нужно отправить пустое сообщение в основной транспорт, чтобы процесс на стороне сервера продолжался.
И на стороне клиента, в методе RequestChannel.Request мы также должны обработать пустое сообщение, которое мы отправили из RequestContext.Reply в этом случае. Просто вернуть ноль должно быть в порядке.
На мой взгляд, у вас вроде есть решение, которое уже работает - отделите ваши односторонние операции от ваших операций запрос-ответ на различные сервисные контракты.
Разница в моделях связи между вашими операциями предполагает, что независимо от того, технически это возможно или нет, вы не должны выставлять эти операции вместе в одном сервисе.
ОБНОВИТЬ
Из вашего комментария звучит так, будто вы пытаетесь внедрить подобный сервис переадресации? Если это так, вы читали это?