blob: 510dc28af1630a8f2e03c75d63d1e96d6f8e6df6 [file] [log] [blame]
Jens Geyeraa0c8b32019-01-28 23:27:45 +01001// Licensed to the Apache Software Foundation(ASF) under one
2// or more contributor license agreements.See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18using System.Threading;
19using System.Threading.Tasks;
20using Thrift.Protocol.Entities;
21
Jens Geyer4115e952023-11-21 23:00:01 +010022#pragma warning disable IDE0079 // net20 - unneeded suppression
23#pragma warning disable IDE0290 // net8 - primary CTOR
24
Jens Geyeraa0c8b32019-01-28 23:27:45 +010025namespace Thrift.Protocol
26{
27 /**
28 * TMultiplexedProtocol is a protocol-independent concrete decorator that allows a Thrift
29 * client to communicate with a multiplexing Thrift server, by prepending the service name
30 * to the function name during function calls.
31 *
32 * NOTE: THIS IS NOT TO BE USED BY SERVERS.
33 * On the server, use TMultiplexedProcessor to handle requests from a multiplexing client.
34 *
35 * This example uses a single socket transport to invoke two services:
36 *
37 * TSocketTransport transport = new TSocketTransport("localhost", 9090);
38 * transport.open();
39 *
40 * TBinaryProtocol protocol = new TBinaryProtocol(transport);
41 *
42 * TMultiplexedProtocol mp = new TMultiplexedProtocol(protocol, "Calculator");
43 * Calculator.Client service = new Calculator.Client(mp);
44 *
45 * TMultiplexedProtocol mp2 = new TMultiplexedProtocol(protocol, "WeatherReport");
46 * WeatherReport.Client service2 = new WeatherReport.Client(mp2);
47 *
48 * System.out.println(service.add(2,2));
49 * System.out.println(service2.getTemperature());
50 *
51 */
52
53 //TODO: implementation of TProtocol
54
55 // ReSharper disable once InconsistentNaming
56 public class TMultiplexedProtocol : TProtocolDecorator
57 {
58 /** Used to delimit the service name from the function name */
59 public const string Separator = ":";
60
61 private readonly string _serviceName;
62
63 /**
64 * Wrap the specified protocol, allowing it to be used to communicate with a
65 * multiplexing server. The <code>serviceName</code> is required as it is
66 * prepended to the message header so that the multiplexing server can broker
67 * the function call to the proper service.
68 *
69 * Args:
70 * protocol Your communication protocol of choice, e.g. TBinaryProtocol
71 * serviceName The service name of the service communicating via this protocol.
72 */
73
74 public TMultiplexedProtocol(TProtocol protocol, string serviceName)
75 : base(protocol)
76 {
77 _serviceName = serviceName;
78 }
79
80 public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken)
81 {
82 switch (message.Type)
83 {
84 case TMessageType.Call:
85 case TMessageType.Oneway:
86 await base.WriteMessageBeginAsync(new TMessage($"{_serviceName}{Separator}{message.Name}", message.Type, message.SeqID), cancellationToken);
87 break;
88 default:
89 await base.WriteMessageBeginAsync(message, cancellationToken);
90 break;
91 }
92 }
93 }
94}