java session 同步_Java web servers 间是如何实现 session 同步的

1 public class Draw extends ReceiverAdapter implementsActionListener, ChannelListener {2 protected String cluster_name="draw";3 private JChannel channel=null;4 private int member_size=1;5 private JFrame mainFrame=null;6 private JPanel sub_panel=null;7 private DrawPanel panel=null;8 privateJButton clear_button, leave_button;9 private final Random random=newRandom(System.currentTimeMillis());10 private final Font default_font=new Font("Helvetica",Font.PLAIN,12);11 private final Color draw_color=selectColor();12 private static final Color background_color=Color.white;13 boolean no_channel=false;14 booleanjmx;15 private boolean use_state=false;16 private long state_timeout=5000;17 private boolean use_unicasts=false;18 protected boolean send_own_state_on_merge=true;19 private final List

members=new ArrayList<>();20

21

22 public Draw(String props, boolean no_channel, boolean jmx, boolean use_state, longstate_timeout,23 boolean use_unicasts, String name, boolean send_own_state_on_merge, AddressGenerator gen) throwsException {24 this.no_channel=no_channel;25 this.jmx=jmx;26 this.use_state=use_state;27 this.state_timeout=state_timeout;28 this.use_unicasts=use_unicasts;29 if(no_channel)30 return;31

32 channel=newJChannel(props).addAddressGenerator(gen).setName(name);33 channel.setReceiver(this).addChannelListener(this);34 this.send_own_state_on_merge=send_own_state_on_merge;35 }36

37 public Draw(JChannel channel) throwsException {38 this.channel=channel;39 channel.setReceiver(this);40 channel.addChannelListener(this);41 }42

43

44 public Draw(JChannel channel, boolean use_state, long state_timeout) throwsException {45 this.channel=channel;46 channel.setReceiver(this);47 channel.addChannelListener(this);48 this.use_state=use_state;49 this.state_timeout=state_timeout;50 }51

52

53 publicString getClusterName() {54 returncluster_name;55 }56

57 public voidsetClusterName(String clustername) {58 if(clustername != null)59 this.cluster_name=clustername;60 }61

62

63 public static voidmain(String[] args) {64 Draw draw=null;65 String props=null;66 boolean no_channel=false;67 boolean jmx=true;68 boolean use_state=false;69 String group_name=null;70 long state_timeout=5000;71 boolean use_unicasts=false;72 String name=null;73 boolean send_own_state_on_merge=true;74 AddressGenerator generator=null;75

76 for(int i=0; i < args.length; i++) {77 if("-help".equals(args[i])) {78 help();79 return;80 }81 if("-props".equals(args[i])) {82 props=args[++i];83 continue;84 }85 if("-no_channel".equals(args[i])) {86 no_channel=true;87 continue;88 }89 if("-jmx".equals(args[i])) {90 jmx=Boolean.parseBoolean(args[++i]);91 continue;92 }93 if("-clustername".equals(args[i])) {94 group_name=args[++i];95 continue;96 }97 if("-state".equals(args[i])) {98 use_state=true;99 continue;100 }101 if("-timeout".equals(args[i])) {102 state_timeout=Long.parseLong(args[++i]);103 continue;104 }105 if("-bind_addr".equals(args[i])) {106 System.setProperty("jgroups.bind_addr", args[++i]);107 continue;108 }109 if("-use_unicasts".equals(args[i])) {110 use_unicasts=true;111 continue;112 }113 if("-name".equals(args[i])) {114 name=args[++i];115 continue;116 }117 if("-send_own_state_on_merge".equals(args[i])) {118 send_own_state_on_merge=Boolean.getBoolean(args[++i]);119 continue;120 }121 if("-uuid".equals(args[i])) {122 generator=new OneTimeAddressGenerator(Long.valueOf(args[++i]));123 continue;124 }125

126 help();127 return;128 }129

130 try{131 draw=newDraw(props, no_channel, jmx, use_state, state_timeout, use_unicasts, name,132 send_own_state_on_merge, generator);133 if(group_name != null)134 draw.setClusterName(group_name);135 draw.go();136 }137 catch(Throwable e) {138 e.printStackTrace(System.err);139 System.exit(0);140 }141 }142

143

144 static voidhelp() {145 System.out.println("\nDraw [-help] [-no_channel] [-props ]" +

146 " [-clustername ] [-state] [-timeout ] [-use_unicasts] " +

147 "[-bind_addr ] [-jmx ] [-name ] [-send_own_state_on_merge true|false] " +

148 "[-uuid ]");149 System.out.println("-no_channel: doesn't use JGroups at all, any drawing will be relected on the " +

150 "whiteboard directly");151 System.out.println("-props: argument can be an old-style protocol stack specification, or it can be " +

152 "a URL. In the latter case, the protocol specification will be read from the URL\n");153 }154

155

156 privateColor selectColor() {157 int red=Math.abs(random.nextInt() % 255);158 int green=Math.abs(random.nextInt() % 255);159 int blue=Math.abs(random.nextInt() % 255);160 return newColor(red, green, blue);161 }162

163

164 private void sendToAll(byte[] buf) throwsException {165 for(Address mbr: members)166 channel.send(newMessage(mbr, buf));167 }168

169

170 public void go() throwsException {171 if(!no_channel && !use_state)172 channel.connect(cluster_name);173 mainFrame=newJFrame();174 mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);175 panel=newDrawPanel(use_state);176 panel.setBackground(background_color);177 sub_panel=newJPanel();178 mainFrame.getContentPane().add("Center", panel);179 clear_button=new JButton("Clear");180 clear_button.setFont(default_font);181 clear_button.addActionListener(this);182 leave_button=new JButton("Leave");183 leave_button.setFont(default_font);184 leave_button.addActionListener(this);185 sub_panel.add("South", clear_button);186 sub_panel.add("South", leave_button);187 mainFrame.getContentPane().add("South", sub_panel);188 mainFrame.setBackground(background_color);189 clear_button.setForeground(Color.blue);190 leave_button.setForeground(Color.blue);191 mainFrame.pack();192 mainFrame.setLocation(15, 25);193 mainFrame.setBounds(new Rectangle(250, 250));194

195 if(!no_channel &&use_state) {196 channel.connect(cluster_name, null, state_timeout);197 }198 mainFrame.setVisible(true);199 setTitle();200 }201

202

203

204

205 voidsetTitle(String title) {206 String tmp="";207 if(no_channel) {208 mainFrame.setTitle(" Draw Demo ");209 return;210 }211 if(title != null) {212 mainFrame.setTitle(title);213 }214 else{215 if(channel.getAddress() != null)216 tmp+=channel.getAddress();217 tmp+=" (" + member_size + ")";218 mainFrame.setTitle(tmp);219 }220 }221

222 voidsetTitle() {223 setTitle(null);224 }225

226 public voidreceive(Message msg) {227 byte[] buf=msg.getRawBuffer();228 if(buf == null) {229 System.err.printf("%s: received null buffer from %s, headers: %s\n", channel.getAddress(), msg.src(), msg.printHeaders());230 return;231 }232

233 try{234 DrawCommand comm=Util.streamableFromByteBuffer(DrawCommand.class, buf, msg.getOffset(), msg.getLength());235 switch(comm.mode) {236 caseDrawCommand.DRAW:237 if(panel != null)238 panel.drawPoint(comm);239 break;240 caseDrawCommand.CLEAR:241 clearPanel();242 break;243 default:244 System.err.println("***** received invalid draw command " +comm.mode);245 break;246 }247 }248 catch(Exception e) {249 e.printStackTrace();250 }251 }252

253 public voidviewAccepted(View v) {254 member_size=v.size();255 if(mainFrame != null)256 setTitle();257 members.clear();258 members.addAll(v.getMembers());259

260 if(v instanceofMergeView) {261 System.out.println("** " +v);262

263 //This is an example of a simple merge function, which fetches the state from the coordinator264 //on a merge and overwrites all of its own state

265 if(use_state && !members.isEmpty()) {266 Address coord=members.get(0);267 Address local_addr=channel.getAddress();268 if(local_addr != null && !local_addr.equals(coord)) {269 try{270

271 //make a copy of our state first

272 Map copy=null;273 if(send_own_state_on_merge) {274 synchronized(panel.state) {275 copy=new LinkedHashMap<>(panel.state);276 }277 }278 System.out.println("fetching state from " +coord);279 channel.getState(coord, 5000);280 if(copy != null)281 sendOwnState(copy); //multicast my own state so everybody else has it too

282 }283 catch(Exception e) {284 e.printStackTrace();285 }286 }287 }288 }289 else

290 System.out.println("** View=" +v);291 }292

293

294 public void getState(OutputStream ostream) throwsException {295 panel.writeState(ostream);296 }297

298 public void setState(InputStream istream) throwsException {299 panel.readState(istream);300 }301

302 /*--------------- Callbacks ---------------*/

303

304

305

306 public voidclearPanel() {307 if(panel != null)308 panel.clear();309 }310

311 public voidsendClearPanelMsg() {312 DrawCommand comm=newDrawCommand(DrawCommand.CLEAR);313 try{314 byte[] buf=Util.streamableToByteBuffer(comm);315 if(use_unicasts)316 sendToAll(buf);317 else

318 channel.send(new Message(null, buf));319 }320 catch(Exception ex) {321 System.err.println(ex);322 }323 }324

325

326 public voidactionPerformed(ActionEvent e) {327 String command=e.getActionCommand();328 switch(command) {329 case "Clear":330 if(no_channel) {331 clearPanel();332 return;333 }334 sendClearPanelMsg();335 break;336 case "Leave":337 stop();338 break;339 default:340 System.out.println("Unknown action");341 break;342 }343 }344

345

346 public voidstop() {347 if(!no_channel) {348 try{349 channel.close();350 }351 catch(Exception ex) {352 System.err.println(ex);353 }354 }355 mainFrame.setVisible(false);356 mainFrame.dispose();357 }358

359 protected void sendOwnState(final Mapcopy) {360 if(copy == null)361 return;362 for(Point point: copy.keySet()) {363 //we don't need the color: it is our draw_color anyway

364 DrawCommand comm=newDrawCommand(DrawCommand.DRAW, point.x, point.y, draw_color.getRGB());365 try{366 byte[] buf=Util.streamableToByteBuffer(comm);367 if(use_unicasts)368 sendToAll(buf);369 else

370 channel.send(new Message(null, buf));371 }372 catch(Exception ex) {373 System.err.println(ex);374 }375 }376 }377

378

379 /*------------------------------ ChannelListener interface --------------------------*/

380

381 public voidchannelConnected(JChannel channel) {382 if(jmx) {383 Util.registerChannel(channel, "jgroups");384 }385 }386

387 public voidchannelDisconnected(JChannel channel) {388 if(jmx) {389 MBeanServer server=Util.getMBeanServer();390 if(server != null) {391 try{392 JmxConfigurator.unregisterChannel(channel, server, cluster_name);393 }394 catch(Exception e) {395 e.printStackTrace();396 }397 }398 }399 }400

401 public voidchannelClosed(JChannel channel) {402

403 }404

405

406 /*--------------------------- End of ChannelListener interface ----------------------*/

407

408

409

410 protected class DrawPanel extends JPanel implementsMouseMotionListener {411 protected final Dimension preferred_size=new Dimension(235, 170);412 protected Image img; //for drawing pixels

413 protectedDimension d, imgsize;414 protectedGraphics gr;415 protected final Mapstate;416

417

418 public DrawPanel(booleanuse_state) {419 if(use_state)420 state=new LinkedHashMap<>();421 else

422 state=null;423 createOffscreenImage(false);424 addMouseMotionListener(this);425 addComponentListener(newComponentAdapter() {426 public voidcomponentResized(ComponentEvent e) {427 if(getWidth() <= 0 || getHeight() <= 0) return;428 createOffscreenImage(false);429 }430 });431 }432

433

434 public void writeState(OutputStream outstream) throwsIOException {435 if(state == null)436 return;437 synchronized(state) {438 DataOutputStream dos=new DataOutputStream(newBufferedOutputStream(outstream));439 //DataOutputStream dos=new DataOutputStream(outstream);

440 dos.writeInt(state.size());441 for(Map.Entryentry: state.entrySet()) {442 Point point=entry.getKey();443 Color col=entry.getValue();444 dos.writeInt(point.x);445 dos.writeInt(point.y);446 dos.writeInt(col.getRGB());447 }448 dos.flush();449 System.out.println("wrote " + state.size() + " elements");450 }451 }452

453

454 public void readState(InputStream instream) throwsIOException {455 DataInputStream in=new DataInputStream(newBufferedInputStream(instream));456 Map new_state=new LinkedHashMap<>();457 int num=in.readInt();458 for(int i=0; i < num; i++) {459 Point point=newPoint(in.readInt(), in.readInt());460 Color col=newColor(in.readInt());461 new_state.put(point, col);462 }463

464 synchronized(state) {465 state.clear();466 state.putAll(new_state);467 System.out.println("read " + state.size() + " elements");468 createOffscreenImage(true);469 }470 }471

472

473 void createOffscreenImage(booleandiscard_image) {474 d=getSize();475 if(discard_image) {476 img=null;477 imgsize=null;478 }479 if(img == null || imgsize == null || imgsize.width != d.width || imgsize.height !=d.height) {480 img=createImage(d.width, d.height);481 if(img != null) {482 gr=img.getGraphics();483 if(gr != null && state != null) {484 drawState();485 }486 }487 imgsize=d;488 }489 repaint();490 }491

492

493 /*---------------------- MouseMotionListener interface-------------------------*/

494

495 public voidmouseMoved(MouseEvent e) {}496

497 public voidmouseDragged(MouseEvent e) {498 int x=e.getX(), y=e.getY();499 DrawCommand comm=newDrawCommand(DrawCommand.DRAW, x, y, draw_color.getRGB());500

501 if(no_channel) {502 drawPoint(comm);503 return;504 }505

506 try{507 byte[] buf=Util.streamableToByteBuffer(comm);508 if(use_unicasts)509 sendToAll(buf);510 else

511 channel.send(new Message(null, buf));512 }513 catch(Exception ex) {514 System.err.println(ex);515 }516 }517

518 /*------------------- End of MouseMotionListener interface ---------------------*/

519

520

521 /**

522 * Adds pixel to queue and calls repaint() whenever we have MAX_ITEMS pixels in the queue523 * or when MAX_TIME msecs have elapsed (whichever comes first). The advantage compared to just calling524 * repaint() after adding a pixel to the queue is that repaint() can most often draw multiple points525 * at the same time.526 */

527 public voiddrawPoint(DrawCommand c) {528 if(c == null || gr == null) return;529 Color col=newColor(c.rgb);530 gr.setColor(col);531 gr.fillOval(c.x, c.y, 10, 10);532 repaint();533 if(state != null) {534 synchronized(state) {535 state.put(newPoint(c.x, c.y), col);536 }537 }538 }539

540

541

542 public voidclear() {543 if(gr == null) return;544 gr.clearRect(0, 0, getSize().width, getSize().height);545 repaint();546 if(state != null) {547 synchronized(state) {548 state.clear();549 }550 }551 }552

553

554 /**Draw the entire panel from the state*/

555 public voiddrawState() {556 //clear();

557 Map.Entry entry;558 Point pt;559 Color col;560 synchronized(state) {561 for(Iterator it=state.entrySet().iterator(); it.hasNext();) {562 entry=(Map.Entry)it.next();563 pt=(Point)entry.getKey();564 col=(Color)entry.getValue();565 gr.setColor(col);566 gr.fillOval(pt.x, pt.y, 10, 10);567

568 }569 }570 repaint();571 }572

573

574 publicDimension getPreferredSize() {575 returnpreferred_size;576 }577

578

579 public voidpaintComponent(Graphics g) {580 super.paintComponent(g);581 if(img != null) {582 g.drawImage(img, 0, 0, null);583 }584 }585

586 }587

588 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值