Commit | Line | Data |
4536f655 |
1 | |
2 | |
3 | Demonstration of Chat Server Emulation |
4 | |
5 | These two demonstration scripts emulate a very simple chat server with 4 |
6 | connected users. They showcase the Stem modules Stem::Switch (which |
7 | multiplexes Stem Messages) and Stem::SockMsg (a socket to message |
8 | gateway). chat_demo and chat2_demo behave the same but the former runs |
9 | as a single Stem Hub (process) and the latter as two Hubs (which can be |
10 | on separate systems - see below to experiment with that). Just like |
11 | with real chat, a user can type into their terminal and their text will |
12 | appear on the windows of other users. The Stem::Switch Cell (configured |
13 | as 'sw') acts as the chat server and it controls which users will see |
14 | the text from other users. You can change that user to user map by |
15 | issuing command messages to the 'sw' Cell (see DEMO for more on entering |
16 | command messages from the terminal). The two demo scripts are described |
17 | in detail below with sections on running, using, configuring and |
18 | experimenting with them. |
19 | |
20 | Running chat_demo |
21 | |
22 | The single Hub chat demonstration is called chat_demo and it uses the |
23 | chat.stem configuration file (found in conf/ and also where you |
24 | installed the demo Stem configurations). It is run with the simple |
25 | command: |
26 | |
27 | chat_demo |
28 | |
29 | To exit, just enter 'quit' in the chat_demo script window itself. It will |
30 | kill all the other windows and then exit. This will also happen if you |
31 | interrupt the demo script with ^C. |
32 | |
33 | If the -s option is used, then all the windows will use ssfe (split |
34 | screen front end which you can install from the Stem distribution) which |
35 | provides a command line edit and history window section and an output |
36 | section. A single Hub window will be created and then 4 smaller telnet |
37 | windows which will be connected to listen sockets in the Stem Hub. These |
38 | telnet windows are the chat users and they can type data and other users |
39 | will see the output. The telnet windows are named A, B, C and D. |
40 | |
41 | Using chat_demo |
42 | |
43 | Now type a line of text into A's window and hit return. Notice how all 4 |
44 | windows see that text. Now do the same for D. Only C will see its |
45 | text. This is controlled by the map in the Stem::Switch Cell named |
46 | 'sw'. You can print out that map by sending a status command message to |
47 | that Cell. In the Hub window (named Stem) type this command: |
48 | |
49 | sw status |
50 | |
51 | You will see this printout: |
52 | |
53 | Status of switch: sw |
54 | |
55 | In Map: |
56 | |
57 | a -> a b c d |
58 | b -> a |
59 | c -> b d |
60 | d -> c |
61 | |
62 | Out Map: |
63 | |
64 | a -> A |
65 | b -> B |
66 | c -> C |
67 | d -> D |
68 | |
69 | This shows that a data message that came in with the Message target 'a' |
70 | will have its data copied to all 4 users and that 'd' will only send |
71 | text to 'c'. The Message target name is used as a key to index into the |
72 | In Map which gets a list of keys to the Out Map. The Out Map is then |
73 | indexed and a list of Cell addresses is found. Those addresses are sent |
74 | a copy of the data message. Now you should be able to predict what will |
75 | happend to text entered on B or C. Note that the internal keys are not |
76 | related to any other namespaces and are private to this Cell. The Switch |
77 | Cell's maps can be changed by command messages sent to this Cell. |
78 | |
79 | Also run this command in the Hub window: |
80 | |
81 | reg status |
82 | |
83 | This sends a status message to the Class Cell Stem::Route which has the |
84 | alias 'reg'. It returns a listing of all registered Cells with their |
85 | Cloned Cell names or Class Cell Aliases. You can run this command in any |
86 | Hub window to find the list of registered Cells. Most of the Class |
87 | Cells support and some Object Cells support status commands which can be |
88 | sent from the console. |
89 | |
90 | |
91 | Configuring chat_demo |
92 | |
93 | Look at the file conf/chat.stem. That is the configuration file used by |
94 | chat_demo. It is very simple and easy to understand. It is a Perl list |
95 | of lists structure with key/value pairs. Read the config_notes for more |
96 | on this. |
97 | |
98 | The first Cell configured is Stem::TtyMsg which supports typing in and |
99 | sending command messages. This Cell is used in all the demo |
100 | configurations. You can use it for any Stem application where you might |
101 | want to enter command messages by hand. |
102 | |
103 | [ |
104 | class => 'Stem::TtyMsg', |
105 | args => [], |
106 | ], |
107 | |
108 | Then come four Stem::SockMsg Cells named A, B, C and D. Each has a |
109 | single server socket listening on its own port. Also they are configured |
110 | (via the 'data_addr' attribute) to send their data to the same 'sw' Cell |
111 | but with the target addresse a, b, c, or d. These Cells allow |
112 | the user telnets to connect to this Hub. |
113 | |
114 | [ |
115 | class => 'Stem::SockMsg', |
116 | name => 'A', |
117 | args => [ |
118 | port => 6666, |
119 | server => 1, |
120 | cell_attr => [ |
121 | 'data_addr' => ':sw:a' |
122 | ], |
123 | ], |
124 | ], |
125 | |
126 | Finally we have the Stem::Switch Cell named 'sw' which controls the |
127 | mapping of users to users. It is just like the output from the first |
128 | status command we did above. It sets the input maps to the list of |
129 | internal target names and the output map is set to Cell addresses that |
130 | redirect the incoming messages. |
131 | |
132 | [ |
133 | class => 'Stem::Switch', |
134 | name => 'sw', |
135 | args => [ |
136 | |
137 | in_map => [ |
138 | |
139 | a => [ qw( a b c d ) ], |
140 | b => 'a', |
141 | c => [ qw( b d ) ], |
142 | d => 'c', |
143 | ], |
144 | |
145 | out_map => [ |
146 | |
147 | a => 'A', |
148 | b => 'B', |
149 | c => 'C', |
150 | d => 'D', |
151 | ], |
152 | ], |
153 | ], |
154 | |
155 | Experimenting with chat_demo |
156 | |
157 | Now try to send a map command message to the 'sw' Cell. Enter this in |
158 | the Hub window: |
159 | |
160 | sw map b b c d |
161 | |
162 | and then type something into B. You should see it print on B, C, and D's |
163 | windows. You can change any of the maps. The 'map' token is the command |
164 | (as was 'status') and b is the input map name you are changing. The rest |
165 | of the tokens are the internal keys to output map. You can always print |
166 | out the map with the status command (as shown above) and verify your |
167 | changes. |
168 | |
169 | Running chat2_demo |
170 | |
171 | You run chat2_demo also by just typing the script name and its basic |
172 | behavior is just like chat_demo. The main difference is that it runs two |
173 | Stem Hubs and the four users are split with two connecting to each |
174 | Hub. So there are two configuration files named chat_server.stem and |
175 | chat_client.stem and they are in conf/ directory. When you run |
176 | chat2_demo, two Hub windows will be created with the names Chat1 and |
177 | Chat2. The two Stem Hubs are called 'server' and 'client' and those |
178 | names only reflect how they initially connect via sockets. Once they are |
179 | properly connected, they communicate in a peer to peer fashion. |
180 | |
181 | Using chat2_demo |
182 | |
183 | You can interact with chat2_demo just as you did with chat_demo. The |
184 | same user to user mapping is in effect and you can enter user text the |
185 | same way and also change the map. In fact you can enter and send all the |
186 | same command messages you did before in either Hub window and you will |
187 | see similar output. The major difference is that 2 of the output map |
188 | Cell addresses have Hub values. |
189 | |
190 | First enter the 'reg status' command in each Hub window. Notice how the |
191 | 'server' Hub (window named Chat1) has the C and D Stem::SockMsg Cells |
192 | and the Stem::Switch Cell named 'sw'. The 'client' Hub (window named |
193 | Chat2) has only the A and B Stem::SockMsg Cells. This means that the |
194 | users connected to the 'client' Hub have to |
195 | |
196 | Now enter this command in each of the two Hub windows: |
197 | |
198 | port status |
199 | |
200 | That sends a 'status' command to the Class Cell Stem::Portal of the Hub. |
201 | |
202 | The 'server' Hub will print: |
203 | |
204 | Portal Status for Hub 'server' |
205 | client => Stem::Portal=HASH(0xd2978) |
206 | |
207 | This shows that this Hub can send messages to another Hub named 'client' |
208 | And the 'client' Hub will print: |
209 | |
210 | Portal Status for Hub 'client' |
211 | DEFAULT => Stem::Portal=HASH(0xd0930) |
212 | server => Stem::Portal=HASH(0xd0930) |
213 | |
214 | This shows that this Hub can send messages to another Hub named 'server' |
215 | and to one named 'DEFAULT' which is the same portal as 'server'. When a |
216 | message doesn't have a Hub name in its 'to' address and it can't be |
217 | delivered locally, it is sent to a Portal named DEFAULT if it can be |
218 | found. This is similar to the default route in IP networks. |
219 | |
220 | How chat2_demo is Configured |
221 | |
222 | Look at the files conf/chat_server.stem and conf/chat_client.stem. They |
223 | are the configuration files used by chat2_demo. They are basically |
224 | copies of chat.stem with support for two hubs and the Stem::SockMsg |
225 | Cells split between them. The new Cell addition to both is Stem::Portal |
226 | which supports send messages between Hubs. The 'server' Hub has this: |
227 | |
228 | [ |
229 | class => 'Stem::Portal', |
230 | args => ['server' => 1 ], |
231 | ], |
232 | |
233 | That makes this Hub a server which listen for connections from other |
234 | Stem Hubs. The default port number is 10,000 (though this will change |
235 | soon). There is no 'host' attribute in that Stem::Portal Cell so it uses |
236 | the localhost interface by default. The 'client' Hub doesn't have a |
237 | server attribute so it is a client and it connects by default to |
238 | localhost and the port 10,000. |
239 | |
240 | [ |
241 | class => 'Stem::Portal', |
242 | args => [], |
243 | ], |
244 | |
245 | Then come four Stem::SockMsg Cells with A and B in stem_client.stem and |
246 | C and D in stem_server.stem. And finally the Stem::Switch Cell named |
247 | 'sw' which is only in stem_server.stem. Note that the output map for 'a' |
248 | and 'b' have the Hub name 'client' in their Cell addresses. This is |
249 | because the A and B users are connecting to the 'client' Hub and this |
250 | Stem::Switch Cell needs to know that so it can send them data. In a more |
251 | realistic chat system, these switch maps would be controlled by end user |
252 | commands and not by entering command messages. |