public class TwitterStreamImpl implements TwitterStream {
public void setUpStream() throws InterruptedException {
final String consumerKey = getTwitterCredentials().get(0).toString();
final String consumerSecret = getTwitterCredentials().get(1).toString();
final String token = getTwitterCredentials().get(2).toString();
final String secret = getTwitterCredentials().get(3).toString();
BlockingQueue<String> queue = new LinkedBlockingQueue<String>(10000);
StatusesFilterEndpoint endpoint = new StatusesFilterEndpoint();
// add some track terms
endpoint.trackTerms(Lists.newArrayList("twitterapi", "#yolo", "trump", "donald", "lol"));
Authentication auth = new OAuth1(consumerKey, consumerSecret, token, secret);
// Authentication auth = new BasicAuth(username, password);
// Create a new BasicClient. By default gzip is enabled.
BasicClient client = new ClientBuilder()
.hosts(Constants.STREAM_HOST)
.endpoint(endpoint)
.authentication(auth)
.processor(new StringDelimitedProcessor(queue))
.build();
// Establish a connection
client.connect();
// Do whatever needs to be done with messages
for (int msgRead = 0; msgRead < 1000; msgRead++) {
if (client.isDone()) {
System.out.println("Client connection closed unexpectedly: " + client.getExitEvent().getMessage());
break;
}
String msg = queue.poll(5, TimeUnit.SECONDS);
if (msg == null) {
System.out.println("Did not receive a message in 5 seconds");
} else {
System.out.println(msg);
}
}
client.stop();
}
/**
* Reads twitterStup.txt from C:/Users/"user"/documents/ and returns them as
* an array
*
* #return Twitter Api Credentials
*/
private ArrayList getTwitterCredentials() {
BufferedReader in;
String str;
ArrayList<String> list = new ArrayList<String>();
try {
in = new BufferedReader(new FileReader("*******"));
while ((str = in.readLine()) != null) {
list.add(str);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return list;
}
The console log says:
Did not receive a message in 5 seconds
And it says that every five seconds.
I want to "sysout" (live) every tweet, that has one of the endpoint trackTerms in it. But there is no error or something similar.
Is there a problem with the proxy perhaps?
The code is working, as it is at the time. The problem was the proxy. Because I've been in the office-network, the connection to the stream wasn't possible. So i tried it with my own notebook, guess what, it worked.
Related
I used to use GCM, now I 've passed to FCM.For this reason, right now, I am sending WebPush Message with Firebase Admin SDK. When I sent webpush, clients get notification without data. According to texts which I read, I have to encyrpt payload with JWT. However I could not find a way to encyrpt.
I've clientAuthSecret, clientPublicKey and endpoint. I need your leadership.
#Override
public WebPushResponse sendMessageToMultipleUsers(List<String> registrationTokens) throws IOException {
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(new ClassPathResource(firebaseConfigPath).getInputStream())).build();
if (FirebaseApp.getApps().isEmpty()) {
FirebaseApp.initializeApp(options);
logger.info("Firebase application has been initialized");
}
MulticastMessage message = MulticastMessage.builder()
.setWebpushConfig(WebpushConfig.builder()
.setNotification(new WebpushNotification("$GOOG up 1.43% on the day",
"$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.", "https://my-server/icon.png"))
.build())
.addAllTokens(registrationTokens).build();
BatchResponse response = null;
try {
response = FirebaseMessaging.getInstance().sendMulticastAsync(message).get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (response != null && response.getFailureCount() > 0) {
List<SendResponse> responses = response.getResponses();
List<String> failedTokens = new ArrayList<>();
for (int i = 0; i < responses.size(); i++) {
if (!responses.get(i).isSuccessful()) {
// The order of responses corresponds to the order of the registration tokens.
failedTokens.add(registrationTokens.get(i));
}
}
System.out.println("List of tokens that caused failures: " + failedTokens);
}
return null;
}
I'm trying to develop an email server which is able to manage three or more clients. Now I'm focusing only on the first client. The mechanism I'm using is this: The client sends its email address (a String) to the server, so he can get into the right directory and extracts the texts from the .txt (which are the emails). This is the structure of the Server directory:
$package
|
+------------+----------------------------+
| | |
Server.java ServerController.java email#email.com/
|
+
+--------|---------+
1.txt 2.txt 3.txt
This is the ServerController file, which is the one that executes the threads:
public class ServerController {
#FXML
private TextArea textarea;
public void initModel() {
try {
int i = 1;
ServerSocket s = new ServerSocket(5000);
while (true) {
Socket incoming = s.accept(); // si mette in attesa di richiesta di connessione e la apre
textarea.setText("Waiting for connections");
Runnable r = new ThreadedEchoHandler(incoming, i);
new Thread(r).start();
i++;
}
} catch (IOException e) {
e.printStackTrace();
}
}
class ThreadedEchoHandler implements Runnable {
private Socket incoming;
private int counter;
/**
* Constructs a handler.
*
* #param i the incoming socket
* #param c the counter for the handlers (used in prompts)
*/
public ThreadedEchoHandler(Socket in, int c) {
incoming = in;
counter = c;
}
public void run() {
String nomeAccount = "";
try {
//PHASE 1: The server receives the email
try {
InputStream inStream = incoming.getInputStream();
Scanner in = new Scanner(inStream);
nomeAccount = in.nextLine(); //ricevo il nome
} catch (IOException ex) {
Logger.getLogger(ServerController.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
incoming.close();
} catch (IOException ex) {
Logger.getLogger(ServerController.class.getName()).log(Level.SEVERE, null, ex);
}
}
//PHASE 2: I'm getting all the emails from the files
File dir = new File(nomeAccount);
String[] tmp = new String[5];
ArrayList<Email> arr = new ArrayList<Email>();
DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
int i = 0;
for (File file : dir.listFiles()) {
if (file.isFile()) {
Scanner input = new Scanner(System.in);
input = new Scanner(file);
while (input.hasNextLine()) {
tmp[i++] = input.nextLine();
}
input.close();
}
Date data = df.parse(tmp[4]);
arr.add(new Email((Integer.parseInt(tmp[0])), tmp[1], nomeAccount, tmp[2], tmp[3], data));
i = 0;
}
//PHASE 3: The server sends the ArrayList to the client
try {
ObjectOutputStream objectOutput = new ObjectOutputStream(incoming.getOutputStream());
objectOutput.writeObject(arr);
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException ex) {
Logger.getLogger(ServerController.class.getName()).log(Level.SEVERE, null, ex);
} catch (ParseException ex) {
Logger.getLogger(ServerController.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
incoming.close();
} catch (IOException ex) {
Logger.getLogger(ServerController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
As you can see I divide it into phases to better understand the mechanism. In the client I've a DataModel which is the one who memorize the email list and that establish the connection with the socket. This is the code:
public void loadData() throws IOException {
Socket s = new Socket("127.0.0.1", 5000);
System.out.println("I've created the socket");
ArrayList<Email> email = new ArrayList<Email>();
//PHASE 1: The client sends a string to the server
try {
InputStream inStream = s.getInputStream();
OutputStream outStream = s.getOutputStream();
PrintWriter out = new PrintWriter(outStream, true /* autoFlush */);
out.print(account); //Sends account name
//PHASE 2: The client receives the ArrayList with the emails
ObjectInputStream objectInput = new ObjectInputStream(s.getInputStream()); //Error Line!
try {
Object object = objectInput.readObject();
email = (ArrayList<Email>) object;
System.out.println(email.get(1));
} catch (ClassNotFoundException e) {
System.out.println("The list list has not come from the server");
e.printStackTrace();
}
} finally {
s.close();
}
//Casting the arrayList
emailList = FXCollections.observableArrayList(email);
//Sorting the emails
Collections.sort(emailList, new Comparator<Email>() {
public int compare(Email o1, Email o2) {
if (o1.getData() == null || o2.getData() == null) {
return 0;
}
return o1.getData().compareTo(o2.getData());
}
});
}
The problem is that when I execute the server I don't get any error but the GUI doesn't load and on the prompt I cannot see any output. If I execute the Client (while the server is running) I only get the message System.out.println("I've created the socket"); but nothing happens after that. What should I modify to let the two sockets communicates?
Using Sockets is bad idea at all. You don't need direct connection.
It's better to use something like REST service with GET and POST.
so you can manage any clients count. Just send response to get and post.
Also you can use tokens.
I am trying to develop a JavaFx application for testing an IPTV. And my task is checking of channel changing successfully. There is no any component or device at the moment. But I am searching for this task, after that I will buy.
My application will send some remote control command over the IR device.
Here is an IR device, but It doesn't have a Java API.
Is there a way for this solution?
I searched and found a device which name was RedRat. It is usb-infrared device that we can use it linux and windows OS.
There is a utility for using it with a programming language.
Here is a sample java code, may be useful for somebody. But you should have a redrat device.
First step, you have to download this redRatHub and paste a direction
secondly, run main class which has same path with redrathub folders.
public class MyDemo {
private static Client client;
private static String DEVICE_NAME = "";
private static String DATA_SET = "";
public static void main(String[] args) {
try {
startRedRat();
client = new Client();
client.openSocket("localhost", 40000);
DEVICE_NAME = client.readData("hubquery=\"list redrats\"").split("]")[1].split("\n")[0].trim();
DATA_SET = client.readData("hubquery=\"list datasets\"").split("\n")[1];
sendCommand("power");
TimeUnit.SECONDS.sleep(5);
sendCommand("btn1", "btn1", "btn1", "btn1");
sendCommand("btnOK");
TimeUnit.SECONDS.sleep(30);
sendCommand("btnBACK");
sendCommand("channel+");
sendCommand("btn6", "btn1");
sendCommand("channel+");
sendCommand("channel-");
sendCommand("volume+");
sendCommand("volume-");
sendCommand("power");
client.closeSocket();
p.destroy();
} catch (Exception ex) {
System.err.println(ex.getMessage());
} finally {
System.out.println("Finished. Hit <RETURN> to exit...");
}
}
private static void sendCommand(String... command) {
try {
for (String cmd : command) {
client.sendMessage("name=\"" + DEVICE_NAME + "\" dataset=\"" + DATA_SET + "\" signal=\"" + cmd + "\"");
TimeUnit.MILLISECONDS.sleep(500);
System.out.println(cmd + " signal send");
}
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void startRedRat() {
try {
SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
#Override
protected Void doInBackground() throws Exception {
p = Runtime.getRuntime().exec("cmd /C C:\\RedRatHub\\RedRatHubCmd.exe C:\\RedRatHub\\TivibuDB.xml");
return null;
}
};
worker.run();
TimeUnit.SECONDS.sleep(5);
} catch (Exception e) {
e.printStackTrace();
}
}
}
this class is communicate with redrat device over the serial ports.
public class Client {
private Socket socket;
private DataOutputStream out;
private DataInputStream in;
/*
* Opens the socket to RedRatHubCmd.
*/
public void openSocket(String host, int port) throws UnknownHostException, IOException {
if (socket != null && socket.isConnected()) return;
socket = new Socket(host, port);
out = new DataOutputStream(socket.getOutputStream());
in = new DataInputStream(socket.getInputStream());
}
/*
* Closes the RedRatHubCmd socket.
*/
public void closeSocket() throws IOException {
socket.close();
}
/*
* Sends a message to the readData() method. Use when returned data from RedRatHub is not needed.
*/
public void sendMessage(String message) throws Exception {
String res = readData(message);
if (!res.trim().equals("OK")) {
throw new Exception("Error sending message: " + res);
}
}
/*
* Reads data back from RedRatHub. Use when returned data is needed to be output.
*/
public String readData(String message) throws IOException {
if (socket == null || !socket.isConnected()) {
System.out.println("\tSocket has not been opened. Call 'openSocket()' first.");
return null;
}
// Send message
out.write((message + "\n").getBytes("UTF-8"));
// Check response. This is either a single line, e.g. "OK\n", or a multi-line response with
// '{' and '}' start/end delimiters.
String received = "";
byte[] inBuf = new byte[256];
while (true) {
// Read data...
int inLength = in.read(inBuf);
//byte[] thisMSg = new byte[inLength];
String msg = new String(Arrays.copyOfRange(inBuf, 0, inLength), "UTF-8");
received += msg;
if (checkEom(received)) return received;
}
}
/*
* Checks for the end of a message
*/
public boolean checkEom(String message) {
// Multi-line message
if (message.trim().endsWith("}")) {
return message.startsWith("{");
}
// Single line message
return message.endsWith("\n");
//return true;
}
}
I'm trying to write a messaging applicaton, and I'm able to send messages (shown as the server client displays the message correctly) but then kicks my client off of the server. The server prints the following error:
java.io.EOFException at
java.io.ObjectInputStream$BlockDataInputStream.peekByte(UnknownSource)
at java.io.ObjectInputStream.readObject0(Unknown Source) at
java.io.ObjectInputStream.readObject(Unknown Source) at
com.liftedstarfish.lifte.gpschat0_2.Server$ClientThread.run(Server.java:243)
My Server Class:
public class Server {
// a unique ID for each connection
private static int uniqueId;
// an ArrayList to keep the list of the Client
private ArrayList<ClientThread> al;
// if I am in a GUI
private ServerGUI sg;
// to display time
private SimpleDateFormat sdf;
// the port number to listen for connection
private int port;
// the boolean that will be turned of to stop the server
private boolean keepGoing;
private String name;
/*
* server constructor that receive the port to listen to for connection as parameter
* in console
*/
public Server(int port, String name) {
this(port, name, null);
}
public Server(int port, String name, ServerGUI sg) {
// GUI or not
this.sg = sg;
// the port
this.port = port;
this.name = name;
// to display hh:mm:ss
sdf = new SimpleDateFormat("HH:mm:ss");
// ArrayList for the Client list
al = new ArrayList<ClientThread>();
}
public void start() {
keepGoing = true;
/* create socket server and wait for connection requests */
try
{
// the socket used by the server
ServerSocket serverSocket = new ServerSocket(port);
// infinite loop to wait for connections
while(keepGoing)
{
// format message saying we are waiting
display("Server waiting for Clients on " + name + ".");
Socket socket = serverSocket.accept(); // accept connection
// if I was asked to stop
if(!keepGoing)
break;
ClientThread t = new ClientThread(socket); // make a thread of it
al.add(t); // save it in the ArrayList
t.start();
}
// I was asked to stop
try {
serverSocket.close();
for(int i = 0; i < al.size(); ++i) {
ClientThread tc = al.get(i);
try {
tc.sInput.close();
tc.sOutput.close();
tc.socket.close();
}
catch(IOException ioE) {
// not much I can do
}
}
}
catch(Exception e) {
display("Exception closing the server and clients: " + e);
}
}
// something went bad
catch (IOException e) {
String msg = sdf.format(new Date()) + " Exception on new ServerSocket: " + e + "\n";
display(msg);
}
}
/*
* For the GUI to stop the server
*/
protected void stop() {
keepGoing = false;
// connect to myself as Client to exit statement
// Socket socket = serverSocket.accept();
try {
new Socket("localhost", port);
}
catch(Exception e) {
// nothing I can really do
}
}
/*
* Display an event (not a message) to the console or the GUI
*/
private void display(String msg) {
String time = sdf.format(new Date()) + " " + msg;
if(sg == null)
System.out.println(time);
else
sg.appendEvent(time + "\n");
}
/*
* to broadcast a message to all Clients
*/
private synchronized void broadcast(String message) {
// add HH:mm:ss and \n to the message
String time = sdf.format(new Date());
String messageLf = time + " " + message + "\n";
// display message on console or GUI
if(sg == null)
System.out.print(messageLf);
else
sg.appendRoom(messageLf); // append in the room window
// we loop in reverse order in case we would have to remove a Client
// because it has disconnected
for(int i = al.size(); --i >= 0;) {
ClientThread ct = al.get(i);
// try to write to the Client if it fails remove it from the list
if(!ct.writeMsg(messageLf)) {
al.remove(i);
display("Disconnected Client " + ct.username + " removed from list.");
}
}
}
// for a client who logoff using the LOGOUT message
synchronized void remove(int id) {
// scan the array list until we found the Id
for(int i = 0; i < al.size(); ++i) {
ClientThread ct = al.get(i);
// found it
if(ct.id == id) {
al.remove(i);
return;
}
}
}
/*
* To run as a console application just open a console window and:
* > java Server
* > java Server portNumber
* If the port number is not specified 1500 is used
*/
public static void main(String[] args) {
// start server on port 1500 unless a PortNumber is specified
int portNumber = 1500;
String serverName = "";
switch(args.length) {
case 1:
try {
portNumber = Integer.parseInt(args[0]);
}
catch(Exception e) {
System.out.println("Invalid port number.");
System.out.println("Usage is: > java Server [portNumber]");
return;
}
case 0:
break;
default:
System.out.println("Usage is: > java Server [portNumber]");
return;
}
// create a server object and start it
Server server = new Server(portNumber, serverName);
server.start();
}
public String getName()
{
return this.name;
}
/** One instance of this thread will run for each client */
class ClientThread extends Thread {
// the socket where to listen/talk
Socket socket;
ObjectInputStream sInput;
ObjectOutputStream sOutput;
// my unique id (easier for deconnection)
int id;
// the Username of the Client
String username;
// the only type of message a will receive
ChatMessage cm;
// the date I connect
String date;
// Constructore
public ClientThread(Socket socket) {
// a unique id
id = ++uniqueId;
this.socket = socket;
/* Creating both Data Stream */
System.out.println("Thread trying to create Object Input/Output Streams");
try
{
// create output first
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
// read the username
username = (String) sInput.readObject();
display(username + " just connected.");
}
catch (IOException e) {
display("Exception creating new Input/output Streams: " + e);
return;
}
// have to catch ClassNotFoundException
// but I read a String, I am sure it will work
catch (ClassNotFoundException e) {
}
date = new Date().toString() + "\n";
}
// what will run forever
public void run() {
// to loop until LOGOUT
boolean keepGoing = true;
while(keepGoing) {
// read a String (which is an object)
try {
//Location of Error
>>>>>>>>>>>>>>>>>>>>cm = (ChatMessage) sInput.readObject();<<<<<<<<<<<<<<<<<
}
catch (IOException e) {
e.printStackTrace();
break;
}
catch(ClassNotFoundException e2) {
e2.printStackTrace();
break;
}
// the messaage part of the ChatMessage
String message = cm.getMessage();
// Switch on the type of message receive
switch(cm.getType()) {
case ChatMessage.MESSAGE:
broadcast(username + ": " + message);
break;
case ChatMessage.LOGOUT:
display(username + " disconnected with a LOGOUT message.");
keepGoing = false;
break;
case ChatMessage.WHOISIN:
writeMsg("List of the users connected at " + sdf.format(new Date()) + "\n");
// scan al the users connected
for(int i = 0; i < al.size(); ++i) {
ClientThread ct = al.get(i);
writeMsg((i+1) + ") " + ct.username + " since " + ct.date);
}
break;
case ChatMessage.ERROR:
broadcast(username + "> " + message);
break;
}
}
// remove myself from the arrayList containing the list of the
// connected Clients
remove(id);
close();
}
// try to close everything
private void close() {
// try to close the connection
try {
if(sOutput != null) sOutput.close();
}
catch(Exception e) {}
try {
if(sInput != null) sInput.close();
}
catch(Exception e) {};
try {
if(socket != null) socket.close();
}
catch (Exception e) {}
}
/*
* Write a String to the Client output stream
*/
private boolean writeMsg(String msg) {
// if Client is still connected send the message to it
if(!socket.isConnected()) {
close();
return false;
}
// write the message to the stream
try {
sOutput.writeObject(msg);
}
// if an error occurs, do not abort just inform the user
catch(IOException e) {
display("Error sending message to " + username);
display(e.toString());
}
return true;
}
}
}
ChatMessage Class:
public class ChatMessage extends AppCompatActivity implements Serializable {
protected static final long serialVersionUID = 1112122200L;
// The different types of message sent by the Client
// WHOISIN to receive the list of the users connected
// MESSAGE an ordinary message
// LOGOUT to disconnect from the Server
static final int WHOISIN = 0, MESSAGE = 1, LOGOUT = 2, ERROR = 3;
private int type;
private String message;
// constructor
public ChatMessage(int type, String message) {
this.type = type;
this.message = message;
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.chat_message);
final TextView lblMessage = (TextView) findViewById(R.id.text_view_message);
if(type == MESSAGE)
lblMessage.setText(message);
}
// getters
public int getType() {
return type;
}
public String getMessage() {
return message;
}
}
From readObject documentation:
ClassNotFoundException - Class of a serialized object cannot be found.
InvalidClassException - Something is wrong with a class used by serialization.
StreamCorruptedException - Control information in the stream is inconsistent.
OptionalDataException - Primitive data was found in the stream instead of objects.
IOException - Any of the usual Input/Output related exceptions.
EOFException is a type of IOException, which is thrown when the end of the file is reached. All though this doesn't throw that particular error, it does throw IOException, meaning it can throw EOFException too.
So in your code, you simply add:
while(sInput.available() > 0){// > 0 means there are bytes to read.
//Read
}
This (in theory) avoids the EOFException. See this for reference
The peer has closed the connection. You should catch this exception separately, and break out of the loop when you catch it. At present you have no provision at all for this condtion.
I've been trying to debug this for 2 hours and i just can't explain it.
I have a server and a client. (server manages some Auctions).
What happens:
The client request something , server sends data back and client receives it just fine.
The client sends something to the server, and the server updates some data.
The client makes the same request as first time (1.), the server send back the updated
data, but the client does not receive the new update data, instead it receives the old data (as it got it in the first request (1.).
The data that is being sent is just a Java Bean with two List-s.
And the code:
// CLIENT CLASS
// creates socket, sends and listens on the socket
// listening is done on a separate thread
public class ServerConnector {
private Socket socket = null;
private ObjectOutputStream out = null;
private Display display;
private ServerListener listener;
public ServerConnector(Display display) {
this.display = display;
try {
socket = new Socket("localhost",33333);
out = new ObjectOutputStream(socket.getOutputStream());
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
listener = new ServerListener(socket, display);
new Thread(listener).start();
}
public void sendRequest(Request request) {
try {
out.writeObject(request);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class ServerListener implements Runnable {
private Socket socket;
private ObjectInputStream in = null;
private Display display;
public ServerListener(Socket socket,Display display) {
this.socket = socket;
this.display = display;
try {
in = new ObjectInputStream(socket.getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void run() {
Response response =null;
try {
while ((response = (Response)in.readObject()) != null) {
if (response.getCars().size() > 0) {
display.showAvailableCars(response.getCars());
}
if(response.getAucs().size() > 0) {
List<Auction> auctionz = response.getAucs();//HERE 1st time it gets the GOOD data, 2nd time should get UPDATED DATA but instead receives the OLD DATA (same as 1st time).
display.showOpenAuctions(auctionz);
}
response = null;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//CLIENT CLASS
// controls when something should be sent, and print out responses
public class Display {
Scanner console = new Scanner(System.in);
ServerConnector server = new ServerConnector(this);
List<Car> cars;
List<Auction> aucs;
public void show() {
int opt = 0;
System.out.println("1. Show available cars for auction.");
System.out.println("2. Show open auctions.");
opt = console.nextInt();
Request request = new Request();
if (opt == 1)
request.setRequest(Request.GET_CARS);
if (opt == 2) {
request.setRequest(Request.GET_OPEN_AUCTIONS);
}
server.sendRequest(request);
}
public void showAvailableCars(List<Car> cars) {
int i = 0;
for (Car c : cars ){
i++;
System.out.println(i +". " + c.getMaker() + " " + c.getModel() + " price: " + c.getPrice());
}
System.out.println("Select car to open Auction for:");
int selectedCar = console.nextInt();
if (selectedCar != 0) {
if (selectedCar <= cars.size()) {
Request request= new Request();
request.setRequest(Request.OPEN_AUCTION);
Car c = cars.get(selectedCar-1);
request.setCar(c);
server.sendRequest(request);
}
}
show();
}
public void setCars(List<Car> cars) {
this.cars = cars;
}
public void showOpenAuctions(List<Auction> aucs2) {
int i = 0;
for (Auction auc : aucs2) {
i++;
System.out.println(i+ ". " + auc.getCar().getModel() + " " + auc.getCar().getMaker() + " last price: " + auc.getPrice());
}
System.out.println("You can now make offers");
System.out.println("Input auction number:");
int selectedAuction = 0;
selectedAuction = console.nextInt();
if (selectedAuction > 0 && selectedAuction <= aucs2.size()) {
System.out.println("Offer new price:");
int price = console.nextInt();
Request request= new Request();
request.setRequest(Request.MAKE_OFFER);
request.setAuctionId(aucs2.get(selectedAuction-1).getId());
request.setPrice(price);
server.sendRequest(request);
}
show();
}
public void setOpenAuctions(List<Auction> aucs2) {
this.aucs = aucs2;
}
}
// SERVER CLASS : send and receives
public class ClientManager implements Runnable {
private AuctionManager manager = new AuctionManagerImpl();
private Socket client;
private ObjectInputStream in = null;
private ObjectOutputStream out = null;
public ClientManager(Socket socket) {
this.client = socket;
try {
in = new ObjectInputStream(client.getInputStream());
out = new ObjectOutputStream(client.getOutputStream());
} catch(Exception e1) {
try {
e1.printStackTrace();
client.close();
}catch(Exception e) {
System.out.println(e.getMessage());
}
return;
}
}
#Override
public void run() {
Request req = null;
try {
while ((req = (Request)in.readObject()) != null) {
if (req.getRequest() != null) {
if (req.getRequest().equals(Request.GET_CARS)) {
Response response = new Response();
response.setCars(manager.getAvailableCars());
out.writeObject(response);
continue;
}
if (req.getRequest().equals(Request.OPEN_AUCTION)) {
manager.openAuction(req.getCar());
continue;
}
if (req.getRequest().equals(Request.GET_OPEN_AUCTIONS)) {
Response response = new Response();
response.setAucs(manager.getHoldedAuctions()); //this line ALWAYS sends to the client GOOD, UPDATED DATA
out.writeObject(response);
out.flush();
continue;
}
if (req.getRequest().equals(Request.MAKE_OFFER)) {
Auction auction = manager.getOpenAuction(req.getAuctionId());
manager.updateAuction(auction, req.getPrice(),client.getRemoteSocketAddress().toString());
continue;
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
It could be because you are using ObjectOutputStreams. Remember that ObjectOutputStreams will cache all objects written to them so that if the same object is written again in the future it can write a back-reference instead of re-writing the whole object. This is necessary when writing an Object graph.
Your code fragment:
if (req.getRequest().equals(Request.GET_CARS)) {
Response response = new Response();
response.setCars(manager.getAvailableCars());
out.writeObject(response);
continue;
}
is writing the object returned by manager.getAvailableCars(). The next time a request is received the same object (but now with different contents) is written - but the ObjectOutputStream doesn't know about the new contents so it just writes a back-reference. The ObjectInputStream at the other end sees the back-reference and returns the same object it read last time, i.e. the original data.
You can fix this by calling ObjectOutputStream.reset() after each response. This will clear the stream's cache.
See ObjectOutputStream.writeUnshared() and .reset().
Ok. I just found out the solution.
from here http://java.sun.com/developer/technicalArticles/ALT/sockets/ :
Object Serialization Pitfall
When working with object serialization it is important to keep in mind that the ObjectOutputStream maintains a hashtable mapping the objects written into the stream to a handle. When an object is written to the stream for the first time, its contents will be copied to the stream. Subsequent writes, however, result in a handle to the object being written to the stream. This may lead to a couple of problems:
If an object is written to the stream then modified and written a second time, the modifications will not be noticed when the stream is deserialized. Again, the reason is that subsequent writes results in the handle being written but the modified object is not copied into the stream. To solve this problem, call the ObjectOutputStream.reset method that discards the memory of having sent an object so subsequent writes copy the object into the stream.
An OutOfMemoryError may be thrown after writing a large number of objects into the ObjectOutputStream. The reason for this is that the hashtable maintains references to objects that might otherwise be unreachable by an application. This problem can be solved simply by calling the ObjectOutputStream.reset method to reset the object/handle table to its initial state. After this call, all previously written objects will be eligible for garbage collection.
The reset method resets the stream state to be the same as if it had just been constructed. This method may not be called while objects are being serialized. Inappropriate invocations of this method result in an IOException.