On this page:
Registration
Receiving Messages
Sending Messages
A complete example
Warning

Client Programs

This write-up is a concise introduction to the creation of world programs that communicate with a server. It is not a guide to the design of client-server systems.

Registration

A world program that wishes to communicate with a server program must register with the server. Registering requires three additional clauses in the big-bang description of the world:

The register clause informs big-bang from where to expect messages and where to send them to. Your programs must register with

"dictionary.ccs.neu.edu"

which is a server that knows how to communicate with your programs.

The port clause specifies which entry point of the server you wish to use. In general, these points are addressed via numbers between 0 and 65,000 (approximately). Most of these ports are usually locked so that the Russian spies can’t steal your email and blackmail you when you become president of Northeastern University. Your programs must choose one of the following ports:

10001, 10002, 10003, 10004, 10005

The name clause sends your credentials to your server. Otherwise it will not allow you to communicate. Your program must send a string of the following shape:

husky.username:0123

The digits represent the last four digits of your student id. Here are some made-up examples:

partner 1

   

credentials

name

   

id

Matt Mac

   

4444

   

"mac.m:4444"

Leena Bot

   

1221

   

"bot.l:1221"

Al Sam-To

   

6789

   

"sam-to.a:6789"

Ma Fell

   

1234

   

"fell.m:1234"

The server will not share the digits of your student ids with its clients.

Receiving Messages

A world program that wishes to receive message must specify the message handler with a on-receive clause. The handler consumes two arguments: the current state of the world and the message that the server sent.

Sending Messages

Until now, our handlers all return a new world state: for example, on-key has signature World String -> World. If we want to send messages to the server, we need a new return type, which means we need to generalize our signature. The newly-generalized return type for all handlers is a union type:
; A HandlerResponse is one of
; - a WorldState
; - a (make-package WorldState Message)

A Package consists of two parts: the next state of the world and a message to be sent to the server on behalf of the world program. Any handler can return packages.

For example, your program might contain this handler definition for mouse events:
(define (mouse-handler w x y me)
  (make-package w "hello world"))
This particular handler would ignore the nature of the mouse event (x, y, and me). Instead, it would return a package that says “the state of the world stays the same” (w) and “please send the "hello world" string” out.

A complete example

; PURPOSE of PROGRAM
 
; This world program connects to a server that sends out one word from a
; dictionary per second. When the client receives a string, it uses it as its
; own state and displays it in the world canvas.
 
; If this client sends a string message to the server, the latter appends it
; to the strings it sends from now on (to this client). The words that a client
; sends out accumulates at the server.  
 
(define the-server "dictionary.ccs.neu.edu")
(define the-port   123456) ; Replace this with the correct port number
 
; Client is String
; interpretation The state of the client is a word.
; It changes every time when a message (string) arrives from the server.
 
; String -> String
; just shows the last word received from the
(define (client s)
  (big-bang s
    [name       "fell.m:1234"]
    [register   the-server]
    [port       the-port]
    [on-tick    send-word 3]
    [to-draw    render-word]
    [on-receive receive-word]))
 
; Client -> Package (of String and String)
; send the word "dd" to the server
(check-expect (send-word "hello") (make-package "hello" "dd"))
(check-expect (send-word "world") (make-package "world" "dd"))
(define (send-word s)
  (make-package s "dd"))
 
; Client -> Image
; render the state of the client as a text image with a 22 font in red
(check-expect (render-word "bye") (text "bye" 22 "red"))
(define (render-word s)
  (text s 22 "red"))
 
; Client String -> Client
; turn the received word into the state of the client
(check-expect (receive-word "bye" "good") "good")
(define (receive-word s m)
  m)

Warning

Do not attempt to run your main function until your handlers pass a solid suite of test cases. Otherwise you will experience nothing but frustration.