Download ticker

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Stock Market Quotes – Socket Version
• The screen will display a stock market ticker
We will reuse our
scrolling banner !
• We will develop two different approaches
• Client Pull – the client periodically contacts the
server and requests updates
• Server Push – the client supplies a list of stocks
it is watching and the server notifies the client
whenever one of these stock changes
• We develop the same two approaches use RMI
(Remote Method Invocation) in the next section
The Overall Design
• Here is the class diagram showing the new classes
• Here is how the program operates
• The client contacts the server for an update
• The server sends back a complete list of (name
quote) pairs for all stocks
• The client picks out those it wants to display
Fields and Methods in the Ticker Class
A Generic Ticker Banner Class - 1
public class Ticker extends DBAnimationApplet {
public void initQuotes() {}
public void initAnimator() {
String att = getParameter("delay");
if (att != null) { setDelay(Integer.parseInt(att)); }
watch = getParameter("watch");
if (att != null) {
StringTokenizer tk = new StringTokenizer(watch);
Vector v = new Vector();
while (tk.hasMoreTokens()) { v.addElement(tk.nextToken()); }
n = v.size();
symbol = new String[n];
quote = new String[n];
for (int i = 0; i < n; i++) {
symbol[i] = (String) v.elementAt(i);
quote[i] = "0";
}
}
url = getDocumentBase();
initQuotes();
updateQuotes();
text1 = text2;
x = d.width;
y = font.getSize();
}
A Generic Ticker Banner Class - 2
public void paintFrame(Graphics g) {
g.setColor(Color.black);
g.fillRect(0,0,d.width,d.height);
// set the font and color, and draw the text
g.setFont(font);
g.setColor(Color.green);
g.drawString(text1 + text2, x, y);
// get the font metrics to determine the length of the text
FontMetrics fm = g.getFontMetrics();
int length = fm.stringWidth(text1);
// adjust the position of text for the next frame
x -= offset;
// if the text is completely off to the left end
// move the position back to the right end
if (x < -length) {
x = 0;
text1 = text2;
updateQuotes();
}
}
A Generic Ticker Banner Class - 3
protected synchronized void updateQuotes() {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < n; i++) {
sb.append(symbol[i] + " " + quote[i] + "
}
text2 = sb.toString();
}
protected String text1, text2;
protected Font font =
new java.awt.Font("Helvetica", Font.BOLD, 24);
protected int speed = 100;
protected int offset = 1;
protected int x, y;
protected int n;
protected String symbol[], quote[];
protected URL url;
protected String watch;
}
");
public class TickerPullClient
extends Ticker {
TickerPullClient
protected void updateQuotes() {
int i;
try {
Socket t = new Socket(url.getHost(), 8001);
BufferedReader in =
new BufferedReader(new InputStreamReader(t.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
StringTokenizer tk = new StringTokenizer(line);
String name = tk.nextToken();
for (i = 0; i < n; i++) {
if (symbol[i].equals(name)) {
String newquote = tk.nextToken();
quote[i] = newquote;
}
}
}
t.close();
} catch (IOException e) {}
super.updateQuotes();
}
}
/*
Protocol --- Ticker client pull
Port:
8001
Client: connect
Server: name1 quote1
name2 quote2
...
Server: disconnect
The Server Side - 1
Server design:
two threads: client handler, quote generator
no synchronization necessary for quote[]
*/
public class QuotePullServer extends Thread {
static protected String symbol[] =
{ "IBM", "Sun", "Intel", "Apple", "Compaq" };
static protected int
quote[] = { 100, 100, 100, 100, 100 };
static protected int
n = 5;
public static void main(String[] args) {
System.out.println("QuotePullServer started.");
new QuotePullServer().start();
try {
ServerSocket s = new ServerSocket(8001);
for (;;) {
Socket incoming = s.accept();
PrintWriter out = new PrintWriter(
new OutputStreamWriter(incoming.getOutputStream()));
for (int i = 0; i < n; i++) {
out.println(symbol[i] + " " + quote[i]);
}
out.flush();
out.close();
incoming.close();
}
} catch (Exception e) {
System.err.println(e);
}
System.out.println("QuotePullServer stopped.");
The Server Side - 2
}
The Server Side - 3
public void run() {
while (true) {
try {
Thread.currentThread().sleep(10000);
System.out.println("New quote:");
for (int i = 0; i < n; i++) {
quote[i] +=
(Math.random()-0.4)*( 10.0*Math.random());
System.out.println(symbol[i] + " " + quote[i]);
}
System.out.println("End quote.");
} catch (Exception e) {
System.err.println(e);
}
}
}
}
The html File
<title>Java Applet Demo: Ticker</title>
<h1>Ticker</h1>
<hr>
<applet code="TickerPullClient.class" width=200 height=30>
<param name=delay value="100">
<param name=watch value="Sun Intel IBM">
</applet>
<p>
<hr>
<applet code="TickerPullClient.class" width=200 height=30>
<param name=speed value="100">
<param name=watch value="Sun Apple Compaq">
</applet>
<hr>
<a href="TickerPullClient.java">The pull client.</a> <br>
<a href="QuotePullServer.java">The pull server.</a> <br>
Server Push Implementation
• The sequence of operations
Server Push Design
• Notice that we reuse our generic Ticker class
/*
Protocol --- Ticker client pull
Port:
8002
Client: connect
Client: WATCH name1 name2 ...
Server: name1 quote1
// send all quotes the first time
name2 quote2
...
Server: DONE
Server: name quote
// resend quote when changed
Server: name quote
...
Client: CLOSE
Client design:
two threads: animator, quote listener
animator waits until all quotes are in
no synchronization necessary for quote[]
*/
The Client
Side
TickerPushClient - 1
public class TickerPushClient extends Ticker {
protected Socket socket;
protected PrintWriter out;
protected QuoteListener quotelistener;
public void initQuotes() {
try {
socket = new Socket(url.getHost(), 8002);
out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
out.println("WATCH " + watch);
out.flush();
System.out.println("Send: " + "WATCH " + watch);
BufferedReader in =
new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println("Receive: " + line);
if (line.trim().equals("DONE")) {
break;
}
TickerPushClient - 2
StringTokenizer tk = new StringTokenizer(line);
String name = tk.nextToken();
for (int i = 0; i < n; i++) {
if (symbol[i].equals(name)) {
String newquote = tk.nextToken();
quote[i] = newquote;
}
}
}
out.flush();
quotelistener = new QuoteListener(this, in);
quotelistener.start();
} catch (IOException e) {
System.err.println(e);
}
}
public void destroy() {
out.println("CLOSE");
quotelistener.interrupt();
}
}
class QuoteListener extends Thread {
public QuoteListener(TickerPushClient ticker, BufferedReader in) {
this.ticker = ticker;
this.in = in;
}
public void run() {
String line;
try {
while ((line = in.readLine()) != null) {
System.out.println("Receive: " + line);
StringTokenizer tk = new StringTokenizer(line);
String name = tk.nextToken();
for (int i = 0; i < ticker.n; i++) {
if (ticker.symbol[i].equals(name)) {
String newquote = tk.nextToken();
ticker.quote[i] = newquote;
}
}
if (isInterrupted()) { break; }
}
in.close();
} catch (IOException e) {
System.out.println(e);
}
}
QuoteListener
public class QuotePushServer extends Thread {
static
static
static
static
protected
protected
protected
protected
String
int
int
Vector
symbol[] = { "IBM", "Sun", "Intel", "Apple", "Compaq" };
quote[] = { 100, 100, 100, 100, 100 };
n = 5;
clients = new Vector();
public static void main(String[] args) {
System.out.println("QuotePullServer started.");
new QuotePushServer().start();
try {
ServerSocket s = new ServerSocket(8002);
// Waiting for new clients
for (;;) {
Socket incoming = s.accept();
ClientHandler newClient = new ClientHandler(incoming);
clients.addElement(newClient);
newClient.start();
}
} catch (Exception e) {
System.err.println(e);
}
QuotePushServer - 1
System.out.println("QuotePullServer stopped.");
}
static public int getQuote(String name) {
for (int i = 0; i < n; i++) {
if (symbol[i].equals(name)) ( return quote[i]; }
}
return 0;
}
// update quote
public void run() {
while (true) {
try {
Thread.currentThread().sleep(10000);
System.out.println("New quote:");
for (int i = 0; i < n; i++) {
int dq = 0;
if (Math.random() < 0.5) {
dq = (int) ((Math.random() - 0.4) * ( 10.0 * Math.random()));
}
if (dq > 0) {
quote[i] += dq;
System.out.println("Changed: " + symbol[i] + " " + quote[i]);
Enumeration enum = clients.elements();
while (enum.hasMoreElements()) {
ClientHandler t = (ClientHandler) enum.nextElement();
t.updateQuote(symbol[i], quote[i]);
}
}
}
System.out.println("End quote.");
} catch (Exception e) { System.err.println(e); }
}
}
QuotePushServer - 2
}
class ClientHandler extends Thread {
protected PrintWriter out;
protected BufferedReader in;
protected Socket socket;
protected String symbol[];
protected int n;
ClientHandler - 1
public ClientHandler (Socket socket) {
this.socket = socket;
try {
out = new PrintWriter(new
OutputStreamWriter(socket.getOutputStream()));
in = new BufferedReader(new
InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
System.err.println(e);
}
}
public void updateQuote(String name, int quote) // see second slide
public void run() // see third slide
}
ClientHandler - 2
public void updateQuote(String name, int quote) {
boolean needToSend = false;
int i;
if (symbol != null) {
for (i = 0; i < n; i++) {
if (symbol[i].equals(name)) {
needToSend = true;
break;
}
}
} else {
needToSend = true;
}
if (needToSend) {
out.println(name + " " + quote);
out.flush();
}
}
public void run() {
try {
String line;
while ((line = in.readLine()) != null) {
System.out.println("Receive: " + line);
if (line.startsWith("WATCH")) {
StringTokenizer tk = new StringTokenizer(line);
tk.nextToken();
Vector v = new Vector();
while (tk.hasMoreTokens()) { v.addElement(tk.nextToken()); }
n = v.size();
symbol = new String[n];
int i;
for (i = 0; i < n; i++) { symbol[i] = (String) v.elementAt(i); }
for (i = 0; i < n; i++) {
out.println(symbol[i] + " " QuotePushServer.getQuote(symbol[i])) }
out.println("DONE"); out.flush();
} else if (line.trim().equals("CLOSE")) { break; }
}
socket.close();
in.close();
out.close();
} catch (IOException e) {
System.err.println(e);
}
QuotePushServer.clients.removeElement(this);
}
Run responds to two
messages: WATCH
and CLOSE
ClientHandler - 3
Using Sockets for a Chat Room
• Briefly describe your approach
to solve the following problem
Use Sockets to Play Tic-Tac-Toe
• Describe how sockets could be used to adapt the tic-tac-toe
game so it can be played from two different clients remotely
Related documents