I'm writing a small MUD style game in Scala. I want to allow users to telnet in to the game (just like in the old days). This really is just a game. It's going to run on a private network. Security is not (yet) a consideration.
The "protocol" consists of lines of text (terminated with CR) sent by the user. The server will reply with lines of text of it's own before waiting for the next line of user's input. In effect this is a REPL style text interface.
Is there a handy library that will do the networking stuff for me? I just want it to open up a port and allow users to connect to the service and start sending and receiving text from the game.
There are plenty of full-featured server libraries (e.g. TwitterServer) which seem to be geared towards Thrift and HTTP. I'm actually after something much simpler. I just want to receive lines of text, and respond with lines of text.
Any ideas about how I might be able to achieve this with the greatest possible simplicity?
Here you go:
val acceptor = new ServerSocket(port)
while(true) {
val socket = acceptor.accept
Future { serve(socket.getInputStream, socket.getOutputStream) } onComplete { socket.close() }
}
Related
I am interested in learning Vapor, so I decided to work on a website that displays government issued weather alerts. Alert distribution is done via a TCP/IP data stream (streaming1.naad-adna.pelmorex.com port 8080).
What I have in mind is to use IBM's BlueSocket (https://github.com/IBM-Swift/BlueSocket) to create a socket, though after this point, I gave it a bit of thought but was unable to come to a conclusion on what the next steps would be.
Alerts are streamed over the data stream, so I am aware the socket would need to be opened and listened on but wasn't able to get to much past that.
A few things with the data stream are that the start and end of an alert is detected using the start and end tags of the XML document (alert and /alert). There are no special or proprietary headers added to the data, it's only raw XML. I know some alerts also include an XML declaration so I assume the encoding should be taken into account if the declaration is available.
I was then thinking of using XMLParser to parse the XML and use the data I am interested in from the alert.
So really, the main thing I am struggling with is, when the socket is open, what would be the method to listen to it, determine the start and end of the alert and then pass that XML alert for processing.
I would appreciate any input, I am also not restricted to BlueSocket so if there is a better option for what I am trying to achieve, I would be more than open to it.
So really, the main thing I am struggling with is, when the socket is
open, what would be the method to listen to it, determine the start
and end of the alert and then pass that XML alert for processing.
The method that you should use is read(into data: inout Data). It stores any available data that the server has sent into data. There are a few reasons for this method to fail, such as the connection disconnecting.
Here's an example of how to use it:
import Foundation
import Socket
let s = try Socket.create()
try s.connect(to: "streaming1.naad-adna.pelmorex.com", port: 8080)
while true {
if try Socket.wait(for: [s], timeout: 0, waitForever: true) != nil {
var alert = Data()
try s.read(into: &alert)
if let message = String(data: alert, encoding: .ascii) {
print(message)
}
}
}
s.close()
First create the socket. The default is what we want, a IPv4 TCP Stream.
Second connect() to the server using the hostname and port. Without this step, the socket isn't connected and cannot receive or send any data.
wait() until hostname has sent us some data. It returns a list of sockets that have data available to read.
read() the data, decode it and print it. By default this call will block if there is no data available on the socket.
close() the socket. This is good practice.
You might also like to consider thinking about:
non blocking sockets
error handling
streaming (a single call to read() might not give a complete alert).
I hope this answers your question.
I'm trying to re-write one of our old Servers using ZeroMQ, for now I have the following Server setup, (which works for Zmq requests):
using (var context = ZmqContext.Create())
using (var server = context.CreateSocket(SocketType.REP)) {
server.Bind("tcp://x.x.x.x:5705");
while (true) { ... }
This kind of setup works fine if I use the Zmq client library to connect context.CreateSocket(SocketType.REQ)
But unfortunately we've got a lot of legacy code that needs to connect to this server and the sockets are created using .net socket libs:
Socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
Socket.Connect(ipAddress, port);
Is there a way to write a ZeroMQ Server to accept these traditional .net socket connections?
You can achieve this using ZMQ_STREAM sockets.
Please note that since zeroMQ 4.x, the RAW router option has been deprecated for a new ZMQ_STREAM socket type, that works the same way as ROUTER + RAW.
It seems it is bound to evolve, though.
I recently tried ZMQ_STREAM sockets in version 4.0.1.
You can open one, use zmq_rcv until you receive the whole message (you have to check it is whole yourself), or zmq_msg_rcv to let ZeroMQ handle it. You will receive an identifier message part, just like the identifier you would find in ROUTER sockets, directly followed by one ONLY body part. There is no empty delimiter between them like there would be using a REQ Socket talking to a ROUTER Socket. So if you route them, be sure to add it yourself.
Beware though: if there is latency on the other end or if your message exceeds ZeroMQ ZMQ_STREAM buffers (mine are 8192 bytes long), your message can be interpreted by zeroMQ as a series of messages.
In that case, you will receive as many different ZeroMQ messages including both the identifier part and the body part, and it is your job to aggregate them, knowing that if several clients are talking to the STREAM socket, they might get mixed up. I personnally use a hash table using the binary identifier as a key, and delete the entry from the table when I know the message is complete and sent to the next node.
Sending through a ZMQ_STREAM with zmq_msg_send or zmq_send works fine as is.
You probably have to use zmq's RAW socket type (instead of REP) to connect with and read client data without zmq-specific framing.
HTTP Server in C (from Pieter's blog)
http://hintjens.com/blog:42
RAW Socket type info
https://github.com/hintjens/libzmq/commit/777c38ae32a5d1799b3275d38ff8d587c885dd55
Is it possible to use a webserver with websockets as a wrapper to another server to pass messages from the "real server" to a web client and back?
Im curious of this as I have a game server written in Ada that has an OS-tied client. I would like to swap this client to a webclient based on Javascript, so that the game can be played in a normal browser. What can be done?
That is the purpose of websockify. It is designed to bridge between WebSocket clients and regular TCP servers. It was created as part of the noVNC which is an HTML5 VNC app that can connect to normal VNC servers. However, websockify is generic and there are now many other projects using it.
Disclaimer: I created websockify and noVNC.
You can easily accomplish this by using AWS:
http://libre.adacore.com/tools/aws/
There's support for websockets in AWS, and you can make use of it's excellent socket (AWS.Net) packages for normal socket support.
Websockets are, contrary to what some people believe, not pure sockets. The raw data is encapsulated and masked by the websocket protocol which isn't widely supported yet. That means an application which wasn't designed for it, you can't communicate with it directly via web sockets.
When you have an application which uses a protocol based on normal sockets, and you want to communicate with it with websockets, there are two options.
Either you use a websocket gateway which does the unpacking / packing of the websocket traffic and forwards it as pure socket traffic to the application. This has the advantage that you needn't modify the application, but it has the disadvantage that it also masks the real IP address of the client which might or might not be a problem for certain applications.
Or you implement websocket in your application directly. This can be done by having two different ports the server listens to, one for normal connections and one for websocket connections. Any data which is received or sent through the websocket-port is sent through your websocket implementation before sending / after receiving it, and otherwise processed by the same routines.
THe Kaazing HTML5 Gateway is a great way of bringing your TCP-based protocol to a web client. The Kaazing gateway basically takes your protocol running on top of TCP and converts it to WebSocket so you can access the protocol in the client. You would still need to write a JavaScript protocol library for the protocol that your back end uses. But if you can work with the protocol on top of TCP, then it's not hard to do it with JavaScript.
I used the following code in ruby to wrapp my sockets. The code was adapted from em-websocket-proxy. There might be some specifics for my project in it but generally switching remote_host and remote_port and connecting to localhost:3000 should set you up with a new connection to your server through a websocket.
require 'rubygems'
require 'em-websocket'
require 'sinatra/base'
require 'thin'
require 'haml'
require 'socket'
class App < Sinatra::Base
get '/' do
haml :index
end
end
class ServerConnection < EventMachine::Connection
def initialize(input, output)
super
#input = input
#output = output
#input_sid = #input.subscribe { |msg| send_data msg+ "\n" }
end
def receive_data(msg)
#output.push(msg)
end
def unbind
#input.unsubscribe(#input_sid)
end
end
# Configuration of server
options = {:remote_host => 'your-server', :remote_port => 4000}
EventMachine.run do
EventMachine::WebSocket.start(:host => '0.0.0.0', :port => 8080) do |ws|
ws.onopen {
output = EM::Channel.new
input = EM::Channel.new
output_sid = output.subscribe { |msg| ws.send msg; }
EventMachine::connect options[:remote_host], options[:remote_port], ServerConnection, input, output
ws.onmessage { |msg| input.push(msg)}
ws.onclose {
output.unsubscribe(output_sid)
}
}
end
App.run!({:port => 3000})
end
Enjoy! And ask if you have questions.
I've been having some problems with the below code that I've pieced together. All the events work as advertised however, when a client drops off-line without first disconnecting the close event doesn't get call right away. If you give it a minute or so it will eventually get called. Also, I find if I continue to send data to the client it picks up a close event faster but never right away. Lastly, if the client gracefully disconnects, the end event is called just fine.
I understand this is related to the other listen events like upgrade and ondata.
I should also state that the client is an embedded device.
client http request:
GET /demo HTTP/1.1\r\n
Host: example.com\r\n
Upgrade: Websocket\r\n
Connection: Upgrade\r\n\r\n
//nodejs server (I'm using version 6.6)
var http = require('http');
var net = require('net');
var sys = require("util");
var srv = http.createServer(function (req, res){
});
srv.on('upgrade', function(req, socket, upgradeHead) {
socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
'Upgrade: WebSocket\r\n' +
'Connection: Upgrade\r\n' +
'\r\n\r\n');
sys.puts('upgraded');
socket.ondata = function(data, start, end) {
socket.write(data.toString('utf8', start, end), 'utf8'); // echo back
};
socket.addListener('end', function () {
sys.puts('end'); //works fine
});
socket.addListener('close', function () {
sys.puts('close'); //eventually gets here
});
});
srv.listen(3400);
Can anyone suggest a solution to pickup an immediate close event? I am trying to keep this simple without use of modules. Thanks in advance.
close event will be called once TCP socket connection is closed by one or another end with few complications of rare cases when system "not realising" that socket been already closed, but this are rare cases. As WebSockets start from HTTP request server might just keep-alive till it timeouts the socket. That involves the delay.
In your case you are trying to perform handshake and then send data back and forth, but WebSockets are a bit more complex process than that.
The handshake process requires some security procedure to validate both ends (server and client) and it is HTTP compatible headers. But different draft versions supported by different platforms and browsers do implement it in a different manner so your implementation should take this in account as well and follow official documentation on WebSockets specification based on versions you need to support.
Then sending and receiving data via WebSockets is not pure string. Actual data sent over WebSockets protocol has data-framing layer, which involves adding header to each message you send. This header has details over message you sending, masking (from client to server), length and many other things. data-framing depends on version of WebSockets again, so implementations will vary slightly.
I would encourage to use existing libraries as they already implement everything you need in nice and clean manner, and have been used extensively across commercial projects.
As your client is embedded platform, and server I assume is node.js as well, it is easy to use same library on both ends.
Best suit here would be ws - actual pure WebSockets.
Socket.IO is not good for your case, as it is much more complex and heavy library that has multiple list of protocols support with fallbacks and have some abstraction that might be not what you are looking for.
The email addresses are stored in a database and the number of people to be emailed each day is variable. I'm not sure yet whether the emails would need to be sent individually or as a mass email. I want recommendations as to what language to use to do this and any other components necessary in a solution.
thanks
In this context, 1,000 people is a pretty small number. I probably wouldn't bother with a database, and I would do the whole thing with the scripting language of my choice (ksh or Lua, in either case piping output to sendmail. This is a very Unix-specific sort of solution.
One thing you may have to watch out for is to throttle the outgoing email—depending on your service provider, if you inject messages into the server at too high a rate, your IP address may be temporarily blacklisted. At home I tell postfix not to deliver more than 1 message per second to Verizon's server.
If I had to write platform-independent code, I would use the LuaSocket library to make a TCP connection directly with a SMTP server. They have a reasonably useful setup for building and sending RFC-compliant messages.
Here is a C# implementation for this:
System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage("from#address.com", "to#address.com", "subject", "body");
System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient("host.address.com", 1234);
client.Send(message);
Just about any modern language can do this. Java, C#, VB.NET, PHP, PERL, Python and many many more.
Sending emails is such a common requirement that most languages and frameworks support it natively.
As for the requirement of up to 1000 emails a day - that's not that many emails and the limiting factor will be limits imposed by an ISP most likely.
In short - use the language and platform you are most comfortable with and find out how email works in that.
As others have mentioned, it's easy to do this in just about any modern language. I'm a fan of Python, which features great scripting capabilities as well as a solid base for building applications. Python's library is well documented, and includes a number of sophisticated features (including the ability to do multipart MIME encoding).
This is from the examples:
# Import smtplib for the actual sending function
import smtplib
# Import the email modules we'll need
from email.mime.text import MIMEText
# Open a plain text file for reading. For this example, assume that
# the text file contains only ASCII characters.
fp = open(textfile, 'rb')
# Create a text/plain message
msg = MIMEText(fp.read())
fp.close()
# me == the sender's email address
# you == the recipient's email address
msg['Subject'] = 'The contents of %s' % textfile
msg['From'] = me
msg['To'] = you
# Send the message via our own SMTP server, but don't include the
# envelope header.
s = smtplib.SMTP()
s.sendmail(me, [you], msg.as_string())
s.quit()
I want recommendations as to what language to use to do this and any other components necessary in a solution
You can do this in whatever language you feel comfortable with. .NET has some nice stuff built in, and you can probably do it in less than 20 lines of code.