The client library contains a number of different ways to connect to a Membase server. First, let's discuss these methods and then we will use one of those methods to make the chat room client application connect with the Membase installation.
There are three main ways of connecting with one or more Membase servers from the client library:
A direct, ASCII protocol connection can be made by creating an instance of the MemcachedClient object and passing in one or more InetSocketAddress instances. For example:
MemcachedClient c = new MemcachedClient(new InetSocketAddress("hostname", portNum));
or:
MemcachedClient c = new MemcachedClient(AddrUtil.getAddresses( "server1:11211 server2:11211"));
Use one of the connection factory constructors to establish a binary protocol connection with your server:
MemcachedClient c = new MemcachedClient( new BinaryConnectionFactory(), AddrUtil.getAddresses("server1:11211 server2:11211"));
Create a connection that is authenticated using SASL by using
a ConnectionFactoryBuilder. The binary
protocol must be used with a SASL authenticated connection. In
the case of Membase, the username and password you use here
are based on the buckets you have defined on the server. The
username is the bucket name, and the password is the password
used when creating the bucket. We will cover this more later,
but in the meantime here is the code you will need to
authenticate and start a binary protocol session:
AuthDescriptor ad = new AuthDescriptor(new String[]{"PLAIN"}, new PlainCallbackHandler(username, password)); MemcachedClient c = new MemcachedClient( new ConnectionFactoryBuilder().setProtocol(Protocol.BINARY) .setAuthDescriptor(ad) .build(), AddrUtil.getAddresses(host));
Let's start making modifications to the tutorial Main.java class
in order to make our first connection. Here we will be making an
unauthenticated ASCII protocol connection to the server. After you
have the tutorial code working, you can easily go back and change
the connect() method to use the binary protocol
instead, or even change it to make an authenticated SASL
connection.
First, modify main to read:
public static void main(String[] args) { if (args.length != 1) { System.err.println("usage: serveraddress"); System.exit(1); } try { new Main().run(args[0]); } catch (Exception ex) { System.err.println(ex); client.shutdown(); } }
Notice that an instance of the class is created and its
run() method is called to get things started,
passing the first argument on the command line to it. This is just
so that we don't have to make everything static. It also sets up a
default exception handler for everything so that the methods will
be much simpler.
Add the run() method, implemented as follows:
public void run(String serverAddress) throws Exception { System.out.println(String .format("Connecting to %s", serverAddress)); connect(serverAddress); client.shutdown(1, TimeUnit.MINUTES); }
Next, add the connect() method:
private void connect(String serverAddress) throws Exception { InetSocketAddress address = new InetSocketAddress(serverAddress, 11211); client = new MemcachedClient(address); }
You'll recognize this constructor as a single server connection. What if you want to know more about the current connection state such as when the connection has been gained, or lost? You can add a connection observer by modifying the connect method and adding the following lines:
client.addObserver(new ConnectionObserver() { public void connectionLost(SocketAddress sa) { System.out.println("Connection lost to "+sa.toString()); } public void connectionEstablished(SocketAddress sa, int reconnectCount) { System.out.println("Connection established with " + sa.toString()); System.out.println("Reconnect count: " + reconnectCount); } });
You've only connected with one server, but what if it goes offline? This can easily be fixed by changing the first three lines of the connect method:
List<InetSocketAddress> addresses = AddrUtil.getAddresses(serverAddress); client = new MemcachedClient(addresses);
The AddrUtil.getAddresses() method takes a
string and parses multiple space delimited server colon port
strings such as:
"server1:11211 server2:11211 10.0.0.1:11211 2001:0DB8:AC10:FE01:::11211"This class will even work with colon-delimited IPv6 addresses.
Finally, you need to create the static member variable to store the client instance at the top of the class:
private static MemcachedClient client;Now you can try compiling and running the application:
$ mvn assembly:assembly $ java -jar target\membasetutorial-exe.jar "10.0.0.33:11211 10.0.0.57:11211" Connecting to 10.0.0.33:11211 10.0.0.57:11211 15-May-2011 5:02:33 PM net.spy.memcached.MemcachedConnection <init> INFO: Added {QA sa=/10.0.0.33:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect q ueue 15-May-2011 5:02:33 PM net.spy.memcached.MemcachedConnection <init> INFO: Added {QA sa=/10.0.0.57:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect q ueue 15-May-2011 5:02:33 PM net.spy.memcached.MemcachedConnection handleIO INFO: Connection state changed for sun.nio.ch.SelectionKeyImpl@1621e42 Connection established with /10.0.0.33:11211 Reconnected count: 1 15-May-2011 5:02:33 PM net.spy.memcached.MemcachedConnection handleIO INFO: Connection state changed for sun.nio.ch.SelectionKeyImpl@b09e89 Connection established with /10.0.0.57:11211 Reconnected count: 1
You can see that the client library outputs some logging
statements indicating that it is making two connections. You can
also see that the connection observer you added to the
connect() method is being called with the
addresses of the two servers as they are connected and the
reconnection count is 1 indicating that the network is in good
shape. It's ready to get some work done.