All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gitee.yanfanvip.replicate.AcrossClusterReceive Maven / Gradle / Ivy

The newest version!
package com.gitee.yanfanvip.replicate;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.jgroups.annotations.MBean;
import org.jgroups.annotations.Property;
import org.jgroups.stack.Protocol;
import org.jgroups.util.UUID;
import org.jgroups.util.Util;

import com.gitee.yanfanvip.cluster.ClusterDatabase;
import com.gitee.yanfanvip.model.Frame;
import com.gitee.yanfanvip.model.ReciveEnum;
import com.gitee.yanfanvip.model.Row;

@MBean(description="数据库接收其他地方推送过来的数据")
public class AcrossClusterReceive extends Protocol implements Runnable {

	@Property(description="Port on which the STOMP protocol listens for requests",writable=false)
    protected int port = 28787;
	protected Thread                    acceptor;
	protected ServerSocket              serverSocket;
	protected ClusterDatabase database;
	protected List connections = new ArrayList<>();
	
	public AcrossClusterReceive() { }
	
	public AcrossClusterReceive(int port){
		this.port = port;
	}
	
	@Override
	public void start() throws Exception {
		database = getProtocolStack().findProtocol(ClusterDatabase.class);
		serverSocket = Util.createServerSocket(getSocketFactory(), "jgroups.stomp.srv_sock", null, port, port+50);
        if(acceptor == null) {
            acceptor=getThreadFactory().newThread(this, "STOMP PULL acceptor");
            acceptor.setDaemon(true);
            acceptor.start();
        }
        new Timer().schedule(new TimerTask() {
			@Override
			public void run() {
				List tmp = new ArrayList<>(connections);
				tmp.forEach(c->{
					try { c.send(ReciveEnum.PING); } catch (Exception e) { }
				});
				tmp.clear();
			}
		}, 30000);
	}
	
	@Override
	public void run() {
		Socket client_sock;
        while(acceptor != null && serverSocket != null) {
            try {
                client_sock = serverSocket.accept();
                Connection conn = new Connection(client_sock);
                Thread thread = getThreadFactory().newThread(conn, "STOMP client connection");
                thread.setDaemon(true);
                thread.start();
            } catch(Exception e) { }
        }
	}
	
	private void pullMessageComplete() {
		System.out.println("拉取消息完成");
	}
	
	public void send(ReciveEnum type) {
		for (Connection c : connections) {
			try {
				c.send(type);
				return;
			} catch (Exception e) { }
		}
	}
	
	class Connection implements Runnable, AutoCloseable{
		protected Socket socket;
		protected final UUID session = UUID.randomUUID();
		protected final DataInputStream in;
	    protected final DataOutputStream out;
	    Lock lock = new ReentrantLock();
		
		public Connection(Socket socket) throws IOException {
			this.socket = socket;
			this.in=new DataInputStream(socket.getInputStream());
	        this.out=new DataOutputStream(socket.getOutputStream());
	        send(ReciveEnum.PING);
	        send(ReciveEnum.PULLDATA);
	        connections.add(this);
		}

		@Override
		public void run() {
			while(socket != null && !socket.isClosed()) {
                try {
                    Frame frame = new Frame(in);
                    Row row = frame.getData();
                    if(frame != null) {
                    	switch (frame.getType()) {
	                    	case PING:{ break; }
							case PUT:{
								database.clusterPut(row.getKeyspaces(), row.getKey(), row.getValue());
								break;
							}
							case PUTALL:{
								database.clusterPutAll(row.getKeyspaces(), row.getValues());
								break;
							}
							case REMOVE:{
								database.clusterRemove(row.getKeyspaces(), row.getKey());
								break;
							}
							case CLEAR:{
								database.clusterClear(row.getKeyspaces());
								break;
							}
							case PULL_MESSAGE_COMPLETE:{
								pullMessageComplete();
								break;
							}
							case SYNC_START:{
								database.getSingleDatabase().clearAll();
								break;
							}
							case SYNC_COMPLETE:{
								System.out.println("同步完成");
								break;
							}
							default: throw new RuntimeException("bad request");
						}
                    }
                } catch(Exception e) {
                    System.out.println("receive close");
                    stop();
                }
            }
		}
		
		private void send(ReciveEnum enum1) throws IOException {
			lock.lock();
			try {
				out.writeInt(enum1.getType());
				out.flush();
			} catch (Exception e) {
				stop();
				throw e;
			}finally {
				lock.unlock();
			}
		}
		
		public void stop() {
			Util.close(in);
	        Util.close(out);
	        Util.close(socket);
	        connections.remove(this);
		}
		
		@Override
		public int hashCode() {
			return this.session.toString().hashCode();
		}
		
		@Override
		public boolean equals(Object obj) {
			return obj.hashCode() == hashCode();
		}

		@Override
		public void close() {
			stop();
		}
	}
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy