2003-01-17 Sebastien Pouliot <spouliot@videotron.ca>
[mono.git] / mcs / class / System.Runtime.Remoting / System.Runtime.Remoting.Channels.Simple / SimpleServerChannel.cs
1 //
2 // System.Runtime.Remoting.Channels.Simple.SimpleServerChannel.cs
3 //
4 // Author: Dietmar Maurer (dietmar@ximian.com)
5 //
6 // 2002 (C) Copyright, Ximian, Inc.
7 //
8
9 using System.Collections;
10 using System.Runtime.Remoting.Messaging;
11 using System.Text.RegularExpressions;
12 using System.Net.Sockets;
13 using System.Net;
14 using System.Threading;
15 using System.IO;
16
17 namespace System.Runtime.Remoting.Channels.Simple
18 {
19         public class SimpleServerChannel : IChannelReceiver, IChannel
20         {
21                 int port = 0;
22                 string name = "simple";
23                 string host;
24                 int priority = 1;
25                 Thread server_thread = null;
26                 TcpListener listener;
27                 SimpleServerTransportSink sink;
28                 ChannelDataStore channel_data;
29                 
30                 void Init (IServerChannelSinkProvider provider) {
31                         if (provider == null) {
32                                 provider = new SimpleServerFormatterSinkProvider ();
33                         }
34                         
35                         IServerChannelSink next_sink = ChannelServices.CreateServerChannelSinkChain (provider, this);
36
37                         host = Dns.GetHostByName(Dns.GetHostName()).HostName;
38                         
39                         string [] uris = null;
40                         
41                         if (port != 0) {
42                                 uris = new String [1];
43                                 uris [0] = GetChannelUri ();
44                         }
45                         
46                         channel_data = new ChannelDataStore (uris);;
47
48                         sink = new SimpleServerTransportSink (next_sink);
49                         
50                         listener = new TcpListener (port);
51                         StartListening (null);
52                 }
53                 
54                 public SimpleServerChannel (int port)
55                 {
56                         this.port = port;
57                         Init (null);
58                 }
59
60                 public SimpleServerChannel (IDictionary properties,
61                                             IServerChannelSinkProvider serverSinkProvider)
62                 {
63                         port = (int)properties ["port"];
64                         Init (serverSinkProvider);
65                 }
66
67                 public SimpleServerChannel (string name, int port,
68                                             IServerChannelSinkProvider serverSinkProvider)
69                 {
70                         name = name;
71                         this.port = port;
72                         Init (serverSinkProvider);
73                 }
74                 
75                 public SimpleServerChannel (string name, int port)
76                 {
77                         name = name;
78                         this.port = port;
79                         Init (null);
80                 }
81                 
82                 public object ChannelData
83                 {
84                         get {
85                                 return channel_data;
86                         }
87                 }
88
89                 public string ChannelName
90                 {
91                         get {
92                                 return name;
93                         }
94                 }
95
96                 public int ChannelPriority
97                 {
98                         get {
99                                 return priority;
100                         }
101                 }
102
103                 string GetChannelUri ()
104                 {
105                         return "simple://" + host + ":" + port;
106                 }
107                 
108                 public string[] GetUrlsForUri (string uri)
109                 {
110                         string [] chnl_uris = channel_data.ChannelUris;
111                         
112                         if (uri.IndexOf ('/') != 0)
113                                 uri = "/" + uri;
114
115                         string [] result = new String [chnl_uris.Length];
116
117                         for (int i = 0; i < chnl_uris.Length; i++) {
118                                 result [i] = chnl_uris [i] + uri;
119                         }
120                         
121                         return result;
122                 }
123
124                 public string Parse (string url, out string objectURI)
125                 {
126                         int port;
127                         
128                         string host = SimpleChannel.ParseSimpleURL (url, out objectURI, out port);
129
130                         return GetChannelUri ();
131                 }
132
133                 void WaitForConnections ()
134                 {
135                         TcpClient client = listener.AcceptTcpClient ();
136                         Stream network_stream = client.GetStream ();
137
138                         while (true) {
139
140                                 sink.InternalProcessMessage (network_stream);
141
142                         }
143                 }
144                 
145                 public void StartListening (object data)
146                 {
147                         if (server_thread == null) {
148                                 listener.Start ();
149                                 if (port == 0) {
150                                         port = ((IPEndPoint)listener.LocalEndpoint).Port;
151                                         channel_data.ChannelUris = new String [1];
152                                         channel_data.ChannelUris [0] = GetChannelUri ();
153                                 }
154
155                                 server_thread = new Thread (new ThreadStart (WaitForConnections));
156                                 server_thread.Start ();
157                         }
158                 }
159
160                 public void StopListening (object data)
161                 {
162                         if (server_thread != null) {
163                                 server_thread.Abort ();
164                                 server_thread = null;
165                                 listener.Stop ();
166                         }
167                 }
168         }
169 }