看了一段时间ttserver的c代码。发现ttserver是根据输入的字符,寻找具体的方法。
数据到达ttserver端以后,就根据传输的代码格式拆包。
要使用tctserver可以修改ttserver-java的protocol包中的方法
增加一个叫misc的类,操作ttserver的misc方法。
package tokyotyrant.protocol;
//import org.jboss.netty.buffer.ChannelBuffer;
//
//import tokyotyrant.helper.BufferHelper;
import java.util.ArrayList;
import java.util.List;
import org.jboss.netty.buffer.ChannelBuffer;
import tokyotyrant.transcoder.ByteArrayTranscoder;
import tokyotyrant.transcoder.StringTranscoder;
import tokyotyrant.transcoder.Transcoder;
import com.dindine.ttserver.util.ListUtil;
/**
* @作用:用方法名,定位缓存数据库使用的
* @author henry
* @date 2010-4-2
*/
public class MISC extends CommandSupport<List<String>> {
private static final PacketFormat RESPONSE = code(false).end();
private final byte[] key;
private List<String> list;
private byte[][] rbuf;
private final int opts;
private final int rnum;
private final List<String> conds;
private static final Transcoder keyTranscoder = new ByteArrayTranscoder();
private static final Transcoder rbufTranscoder = new ByteArrayTranscoder();
private static final Transcoder VALUE_TRANSCODER = new StringTranscoder();
public MISC(String funcName, int opts, List<String> lstr, PacketFormat REQUEST) {
// TODO Auto-generated constructor stub
super((byte) 0x90, REQUEST, RESPONSE, keyTranscoder, rbufTranscoder);
key = ListUtil.strToBytes(funcName);
this.opts = opts;
if(lstr == null) {
rnum = 0;
} else {
rnum = lstr.size();
}
conds = lstr;
rbuf = new byte[rnum][];
}
@Override
protected void pack(PacketContext context) {
// TODO Auto-generated method stub
context.put("nsiz", key.length);
context.put("opts", opts);
context.put("rnum", rnum);
context.put("name", key);
for (int i = 0; i < rnum; i++) {
rbuf[i] = ListUtil.strToBytes(conds.get(i));
context.put("rsiz"+i, rbuf[i].length);
context.put("rbuf"+i, rbuf[i]);
}
if(conds != null)
conds.clear();
}
@Override
protected void unpack(PacketContext context) {
// TODO Auto-generated method stub
code = (Byte) context.get("code");
}
public boolean decode(ChannelBuffer in) {
if (in.readableBytes() < 1) {
return false;
}
code = in.readByte();
int rnum = in.readInt();
list = new ArrayList<String>(rnum);
for (int i = 0; i < rnum; i++) {
if(in.readableBytes() < 4) {
return false;
}
int len = in.readInt();
if(in.readableBytes() < len) {
return false;
}
byte[] value = new byte[len];
in.readBytes(value);
list.add((String)VALUE_TRANSCODER.decode(value));
}
return true;
}
@Override
public List<String> getReturnValue() {
// TODO Auto-generated method stub
if (isSuccess()) {
return list;
} else {
return null;
}
}
}
这段是我的misc的java代码组装格式。
在RDB.java中加入如下方法
public Object misc(String funcName, int opts, List<String> conds) {
PacketFormatBuilder builder = new PacketFormatBuilder();
builder.magic().int32("nsiz").int32("opts").int32("rnum").bytes("name", "nsiz");
int len = 0;
if(conds != null) {
len = conds.size();
}
for (int i = 0; i < len; i++) {
builder.int32("rsiz" + i);
builder.bytes("rbuf" + i, "rsiz" + i);
}
PacketFormat request = builder.end();
return execute(new MISC(funcName, opts, conds, request));
}
funcName就是要使用的方法名。
具体传输可以参考php-tyrant或jtokyotyrant类库写法。