Commit ef91a390 authored by Colomban Wendling's avatar Colomban Wendling
Browse files

OVCCServer: make use of OVCC.Network.Message and add a dummy test client

parent a93843f2
src/*.c
src/ovccserver
src/ovccclient
bin_PROGRAMS = ovccserver
bin_PROGRAMS = ovccserver ovccclient
ovccserver_CPPFLAGS = -DG_LOG_DOMAIN=\"OVCCServer\"
ovccserver_VALAFLAGS = $(VALAFLAGS)
ovccserver_SOURCES = server.vala
ovccserver_VALAFLAGS = $(VALAFLAGS) --thread
ovccserver_SOURCES = client.vala \
server.vala \
servermain.vala
ovccclient_CPPFLAGS = -DG_LOG_DOMAIN=\"OVCCClient\"
ovccclient_VALAFLAGS = $(VALAFLAGS) --thread
ovccclient_SOURCES = client.vala \
clientmain.vala \
server.vala
/*
*
* Copyright (C) 2011 Colomban Wendling <ban@herbesfolles.org>
* Jonathan Michalon <studios.chalmion@no-log.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
using OVCC.Network;
public class Client: Object
{
protected SocketConnection connection = null;
protected DataInputStream input;
protected DataOutputStream output;
public Client ()
{
}
public new bool connect (SocketConnection conn)
throws Error
requires (connection == null)
{
connection = conn;
input = new DataInputStream (connection.input_stream);
output = new DataOutputStream (connection.output_stream);
/* here, may authenticate */
return true;
}
public new bool disconnect ()
throws Error
requires (connection != null)
{
return connection.socket.close ();
}
public bool send (Message msg,
Cancellable? cancel = null)
throws Error
requires (connection != null)
{
return msg.send (output, cancel);
}
public Message? receive (Cancellable? cancel = null)
throws Error
requires (connection != null)
{
return Message.receive (input, cancel);
}
}
/*
*
* Copyright (C) 2011 Colomban Wendling <ban@herbesfolles.org>
* Jonathan Michalon <studios.chalmion@no-log.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
using OVCC.Network;
class MClient: Client
{
protected SocketClient sockclient;
construct
{
sockclient = new SocketClient ();
}
public MClient ()
{
}
public new bool connect (SocketConnectable conn)
throws Error
{
return base.connect (sockclient.connect (conn));
}
}
public static int main (string[] args)
{
string name = "Unnamed client";
string host = "localhost";
if (args.length > 1) {
name = args[1];
}
if (args.length > 2) {
host = args[2];
}
var client = new MClient ();
client.connect (NetworkAddress.parse (host, 0xdead));
//client.receive ().handle (null, client);
client.send (new WelcomeMessage ("Hello"));
client.send (new WelcomeMessage ("I'm %s".printf (name)));
client.send (new DisconnectMessage ());
//client.disconnect ();
return 0;
}
......@@ -18,34 +18,33 @@
*
*/
using OVCC.Network;
/* TODO: add a Source to be notified of incoming messages asynchronously */
public class Server: ThreadedSocketService
{
protected MainLoop loop = new MainLoop (null, false);
private List<Client> clients = null;
public string name { get; construct; }
public uint port { get; construct; default = 0xdead; }
public signal void stopped ();
/* receive a line from @socket */
private static string receive_line (Socket socket,
uint max_len = 255)
throws Error
{
var buf = new char[max_len + 1];
var rcv = socket.receive ((string)buf, max_len);
buf[rcv] = 0;
return ((string)buf).strip ();
}
private static bool send_line (Socket socket,
string line)
private bool send_all (Message message,
Client? exclude = null,
Cancellable? cancel = null)
throws Error
{
var msg = line.strip () + "\n";
return socket.send (msg, msg.length) >= 0;
lock (this.clients) {
foreach (var c in this.clients) {
if (c != exclude) {
c.send (message, cancel);
}
}
}
return true;
}
private bool handle_connection (ThreadedSocketService service,
......@@ -53,77 +52,49 @@ public class Server: ThreadedSocketService
Object? source)
{
debug ("New connection");
var socket = connection.socket;
var client = new Client ();
try {
send_line (socket, "Welcome to server %s".printf (this.name));
} catch {
client.connect (connection);
} catch (Error e) {
warning ("error connecting client: %s", e.message);
return false;
}
bool running = true;
uint bad_count = 0;
while (running)
{
lock (this.clients) {
this.clients.prepend (client);
}
try {
client.send (new WelcomeMessage ("Welcome to server %s".printf (this.name)));
} catch {}
var running = true;
while (running) {
Message? msg;
try {
bool bad = false;
string? msg = null;
var line = receive_line (socket).down ();
debug ("""received "%s"""", line);
switch (line) {
case "sht":
case "shutdown":
msg = "YOU KILLED ME ;(";
running = false;
this.stop();
break;
case "\004": // EOF
case "eof":
msg = "Bye!";
running = false;
break;
case "hlo":
case "hello":
case "hi":
msg = "Hi you!";
break;
case "who":
msg = """Server name is "%s"""".printf (this.name);
break;
case "42":
msg = "You just LOST the game!";
break;
default:
bad = true;
msg = "Sorry, I don't undesrtand what you mean";
break;
}
if (bad) {
bad_count ++;
if (bad_count > 2) {
msg = "We don't seem to speak the same language, sorry.";
running = false;
}
} else if (bad_count > 0) {
bad_count--;
}
if (msg != null) {
debug ("""answering "%s"""", msg);
send_line (socket, msg);
}
msg = client.receive ();
} catch (Error e) {
warning ("error receiving data: %s", e.message);
break;
}
if (msg == null) {
debug ("Invalid message received");
continue;
}
debug ("Message type %s received", msg.get_type ().name ());
if (msg is StringMessage) {
debug (" --- %s", (msg as StringMessage).message);
}
switch (msg.message_type) {
case MessageType.DISCONNECT: running = false; break;
}
}
lock (this.clients) {
this.clients.remove (client);
}
connection.socket.close ();
try { client.disconnect (); } catch { /* we don't care if disconnection failed */ }
debug ("Closed connection");
return true;
}
......@@ -152,25 +123,3 @@ public class Server: ThreadedSocketService
this.stopped ();
}
}
public static int main (string[] args)
{
string name = "Unnamed server";
uint16 port = 0xdead;
if (args.length > 1) {
name = args[1];
}
if (args.length > 2) {
port = (uint16)int.parse (args[2]);
}
var loop = new MainLoop (null, false);
var server = new Server (name, port);
server.stopped.connect (() => loop.quit ());
server.start ();
loop.run ();
return 0;
}
/*
*
* Copyright (C) 2011 Colomban Wendling <ban@herbesfolles.org>
* Jonathan Michalon <studios.chalmion@no-log.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
public static int main (string[] args)
{
string name = "Unnamed server";
uint16 port = 0xdead;
if (! Thread.supported ()) {
critical ("cannot run without thread support");
return 1;
}
if (args.length > 1) {
name = args[1];
}
if (args.length > 2) {
port = (uint16)int.parse (args[2]);
}
var loop = new MainLoop (null, false);
var server = new Server (name, port);
server.stopped.connect (() => loop.quit ());
server.start ();
loop.run ();
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment