看了一段时间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类库写法。