package spimedb.server; import com.google.common.collect.Lists; import io.undertow.websockets.core.WebSocketChannel; import io.undertow.websockets.spi.WebSocketHttpExchange; import jcog.io.Twokenize; import spimedb.MutableNObject; import spimedb.NObject; import spimedb.NObjectConsumer; import spimedb.SpimeDB; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; /** * Created by me on 3/30/17. * TODO make the NObjectConsumer impl an inner class and extend OnTag */ public class AnonymousSession extends Session { //final ConcurrentHashMap<String, Integer> filter = new ConcurrentHashMap(); public AnonymousSession(SpimeDB db) { super(db); sessionID = SpimeDB.uuidString(); set("me", new API()); } @Override protected void onConnected(WebSocketChannel socket) { if (chan.size() == 1) { //first one? synchronized (chan) { if (chan.size() == 1) { //check again. the first one only elides synchronization in non-empty case tag("", +1); } } } statusChange(socket, "connect"); } private void statusChange(WebSocketChannel socket, String status) { db.add( new MutableNObject(sessionID + '/' + serial.incrementAndGet(), status + " "+ socket.getDestinationAddress() )); } @Override protected void onDisconnected(WebSocketChannel socket) { if (chan.isEmpty()) { //last one? // synchronized (chan) { // if (chan.isEmpty()) { //check again. the first one only elides synchronization in non-empty case // filter.clear(); // } // } } statusChange(socket, "disconnect"); } final String sessionID; final AtomicInteger serial = new AtomicInteger(); public class API { public void tell(String[] tags, String message) { MutableNObject n = new MutableNObject(sessionID + "/" + serial.incrementAndGet(), message); ArrayList<String> tt = Lists.newArrayList(tags); List<Twokenize.Span> sp = Twokenize.twokenize(message); for (Twokenize.Span s : sp) { String c = s.content.trim(); switch (s.pattern) { case "hashtag": c = c.substring(1); //remove hashtag break; case "emoticon": case "url": case "mention": case "email": break; default: c = null; } if (c!=null) tt.add(c); } n.when(System.currentTimeMillis()); n.withTags( //Iterables.concat( tt //Collections.singletonList(chan.getDestinationAddress().toString()) //) ); //TODO decorate with: geo-ip, etc db.add(n); } } public void tag(String s, int v) { // filter.compute(s, (ss, e) -> { // if (v == 0) { // if (e!=null) // db.onTag.off(ss, this); // return null; // }else { // if (e == null) { // db.onTag.on(ss, this); // } // return v; // } // }); } //static final Cache<String,TagSession> tagListeners = Caffeine.newBuilder().weakValues().build(); static TagSession tag(SpimeDB db, String tag) { //return tagListeners.get(tag, t -> { return new TagSession(db) { @Override protected void onConnected(WebSocketChannel socket) { super.onConnected(socket); db.onTag.on(tag, this); } @Override public void onConnect(WebSocketHttpExchange exchange, WebSocketChannel socket) { super.onConnect(exchange, socket); } @Override protected void onDisconnected(WebSocketChannel socket) { db.onTag.off(tag, this); super.onDisconnected(socket); } }; //}); } public static class TagSession extends Session implements NObjectConsumer { public TagSession(SpimeDB db) { super(db); } @Override public void accept(NObject nObject) { chan.forEach(c -> sendJSONBinary(c, nObject)); } } }