`
mysh
  • 浏览: 29510 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

zk 与 flash 交互 - FlashContainer

阅读更多

前阵子搞 zk 与 flash 交互,搞得头破血流,zk 本身带有 flash 标签,但只能当播放器用,没法进行比较复杂的 flash 控制,如调用 flash 的内部方法。flash 也没法直接通过前端与 zk 组件交互,于是自己搞了一个中间件,用于 zk 与 flash 的交互,使得 zk 可以直接调用 flash 的内部方法,flash 可以直接向 zk 发送数据,同时加入了一点同步控制,因为 flash 虚拟机是异步单线程的,且 zk 的每个 flash 调用都是独立的,在实际执行过程中无法保证调用顺序。

需要 zk 5.0 以上版本,flash 支持 flex sdk3 和 sdk4 编译程序。

 

demo.zul(zk 演示页面) 

<?page title="demoZK" contentType="text/html;charset=UTF-8"?>
<zk>
	<window title="demoZK" border="normal" width="100%" height="100%"
		apply="mysh.Demo">
		<div id="flashDiv" />
	</window>
</zk>

 

Demo.java(zk 端演示组件)

package mysh;

import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.util.GenericComposer;
import org.zkoss.zul.Div;
import org.zkoss.zul.Messagebox;

import mysh.FlashContainer;

/**
 * Demo.
 * 
 * @version Revision 1.0.0
 */
public class Demo extends GenericComposer {
    
    /*
     * @see org.zkoss.zk.ui.ext.AfterCompose#afterCompose()
     */
    @Override
    public void doAfterCompose(Component comp) {
        Div flashDiv = (Div) comp.getFellow("flashDiv");
        flashDiv.addEventListener(FlashContainer.ON_CONTAINER_INFO,
            new EventListener() {
                public void onEvent(Event event) throws Exception {
                    Messagebox.show("receive from flash : " + event.getData(),
                        "zk msg", Messagebox.OK, Messagebox.INFORMATION);
                }
            });
        
        FlashContainer flashContainer = FlashContainer.genFlashContainer(
            flashDiv, "demoFlash.swf");
        
        flashContainer.registObserver(flashDiv);
        
        flashContainer.callFlash("func1", "param");
    }
    
}

 

 

demoFlash. mxml(flash 端演示)

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   applicationComplete="init()"
			   xmlns:mx="library://ns.adobe.com/flex/mx"
			   width="594"
			   height="416">

	<fx:Script>
		<![CDATA[
			import mysh.FlashContainer;

			import mx.controls.Alert;

			private var flashContainer:FlashContainer;

			private function init():void
			{
				this.flashContainer=new FlashContainer(this);
				this.flashContainer.registFunc("func1", this.function1);
			}

			private function function1(param:String):void
			{
				Alert.show("msg from zk : " + param);
			}

			protected function send2ZK_clickHandler(event:MouseEvent):void
			{
				this.flashContainer.sendEvent2ZK(this.input.text);
			}
		]]>
	</fx:Script>
	<s:Button id="send2ZK"
			  x="46"
			  y="101"
			  label="发送到 zk"
			  click="send2ZK_clickHandler(event)"/>
	<s:TextInput id="input"
				 x="45"
				 y="56"/>

</s:Application>

 

 

 

flashContainer.as(flash 端组件。D.eval 下载地址

package mysh
{ import flash.external.ExternalInterface; import mx.controls.Alert; import mx.core.Application; import r1.deval.D; /** * flash 容器 * * @version 20110117 */ public class FlashContainer { /** * 容器持有者 */ private var holder:Object; /** * 发送事件调用的JS方法 */ private var eventSendFunc:String; /** * 所有注册方法 */ private var funcs:Object=new Object(); /** * 执行顺序 */ private var order:Number=0; public function FlashContainer(holder:Object) { this.holder=holder; // sdk3 : this.eventSendFunc=Application.application.parameters.eventFunc; // sdk4 : // this.eventSendFunc=FlexGlobals.topLevelApplication.parameters.eventFunc; ExternalInterface.addCallback("jsCall", jsCall); } /** * 外部js调用的方法 */ private function jsCall(jsonStr:String):void { // Alert.show(jsonStr); var jsonObj:Object=D.eval(jsonStr); var funcArray:Array=jsonObj.funcs as Array; var order:Number=jsonObj.order as Number; // 检查执行顺序,若 小于0,则执行;若 大于0,则只有 大于 this.order 才执行 if (order > 0) { if (order > this.order) { this.order=order; } else { return; } } // Alert.show(order+","+this.order); for each (var pack:Object in funcArray) { var func:String=pack.func; var args:Array=pack.args; var treatedArgs:Array=new Array(); for (var i:int=0; i < args.length; i++) { treatedArgs[i]=(args[i] as String).replace(/&quot;/g, "\"").replace(/&apos;/g, "'"); } if (this.funcs[func] == null) { Alert.show("FlashContainer 找不到方法:" + func, "内部错误"); return; } (this.funcs[func] as Function).apply(this.holder, treatedArgs); } } /** * 注册方法名 * @param func 方法名 * @param method 方法实体 */ public function registFunc(func:String, method:Function):void { if (func == null || func == "" || method == null) { throw new Error("方法名或方法不能为空"); } this.funcs[func]=method; } /** * 发送事件到 zk * @param value 值 */ public function sendEvent2ZK(value:String):void { // Alert.show(this.eventSendFunc); ExternalInterface.call(this.eventSendFunc, value); } } }
 

 

 

flashContainer.zul(zk 页面)

<?page title="" contentType="text/html;charset=UTF-8"?>
<zk>
	<window title="" border="normal"
		use="FlashContainer">
	</window>
</zk>
 

 

FlashContainer.java(zk端组件。swfobject.js 下载地址。随着功能的增加,我觉得叫 FlashManager 比较合适)

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicLong;

import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.ext.AfterCompose;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Div;
import org.zkoss.zul.Script;
import org.zkoss.zul.Window;

/**
 * flash容器.
 * 非线程安全,需要外部同步.
 * 
 * @version 20110117
 */
public final class FlashContainer extends Window implements AfterCompose {
    
    /**
     * serialVersionUID.
     */
    private static final long   serialVersionUID = 2564493195082621543L;
    
    /**
     * zul 页面地址.
     */
    private static final String ZUL_PATH         = "flashContainer.zul";
    
    /**
     * 方法调用定义.
     * 
     * @version Revision 1.0.0
     */
    public static final class FlashFuncInvoke {
        
        /**
         * 方法名.
         */
        private String   func;
        
        /**
         * 方法参数.
         */
        private String[] args;
        
        /**
         * 构造器.
         * 
         * @param tFunc
         *            方法名
         * @param tArgs
         *            方法参数
         */
        public FlashFuncInvoke(String tFunc, String... tArgs) {
            if (tFunc == null || tFunc.length() == 0 || tArgs == null) {
                throw new RuntimeException("非法参数");
            }
            this.func = tFunc;
            this.args = tArgs;
        }
        
        /**
         * 返回一个“单元素列表”.
         * 
         * @param tFunc
         *            方法名
         * @param tArgs
         *            方法参数
         * @return 单元素列表
         */
        public static List<FlashFuncInvoke> genSingleEleList(String tFunc,
            String... tArgs) {
            List<FlashFuncInvoke> funcList = new ArrayList<FlashContainer.FlashFuncInvoke>(
                1);
            funcList.add(new FlashFuncInvoke(tFunc, tArgs));
            return Collections.unmodifiableList(funcList);
        }
        
    }
    
    /**
     * 用于浏览器端向服务端发送事件.
     */
    private static final String ON_CIENT_INFO     = "onClientInfo";
    
    /**
     * flash 容器事件的名称,用于取得此容器发送的事件(从客户端取得的事件).
     */
    public static final String  ON_CONTAINER_INFO = "onContainerInfo";
    
    /**
     * 执行顺序号限制(2^52-1).
     */
    private static final long   ORDER_LIMIT       = 0xFFFFFFFFFFFFFL;
    
    /**
     * 执行顺序号生成器.
     */
    private final AtomicLong    orderGen          = new AtomicLong(1L);
    
    /**
     * 事件监听组件.
     */
    private Div                 eventListener     = new Div();
    
    /**
     * flash 容器.
     */
    private Div                 flash             = new Div();
    
    /**
     * 浏览器端脚本容器.
     */
    private Script              script            = new Script();
    
    /**
     * 浏览器 js 方法命名空间.
     */
    private String              ns;
    
    /**
     * flash动作观察者.
     */
    private Queue<Component>    observers         = new LinkedList<Component>();
    
    /**
     * 生成 FlashContainer(用于 flash 9 版本).
     * 
     * @param parent
     *            flash容器的父组件
     * @param swfSrc
     *            页面 js 可访问的 swf 路径
     * @return FlashContainer
     */
    public static FlashContainer genFlashContainer(Component parent,
        String swfSrc) {
        Map<String, String> args = new HashMap<String, String>();
        args.put("flashSrc", swfSrc);
        args.put("flashVer", "9");
        return (FlashContainer) Executions.createComponents(
            FlashContainer.ZUL_PATH, parent, args);
    }
    
    /**
     * 生成 FlashContainer(用于 flash 10 版本).
     * 
     * @param parent
     *            flash容器的父组件
     * @param swfSrc
     *            页面 js 可访问的 swf 路径
     * @return FlashContainer
     */
    public static FlashContainer genFlashContainerVer10(Component parent,
        String swfSrc) {
        Map<String, String> args = new HashMap<String, String>();
        args.put("flashSrc", swfSrc);
        args.put("flashVer", "10");
        return (FlashContainer) Executions.createComponents(
            FlashContainer.ZUL_PATH, parent, args);
    }
    
    /**
     * 生成 FlashContainer(用于 flash 10 版本).
     * 
     * @param parent
     *            flash容器的父组件
     * @param swfSrc
     *            页面 js 可访问的 swf 路径
     * @param flashVars
     *            传递给 flash 的参数
     * @return FlashContainer
     */
    public static FlashContainer genFlashContainerVer10(Component parent,
        String swfSrc, Map<String, String> flashVars) {
        Map<String, Object> args = new HashMap<String, Object>();
        args.put("flashSrc", swfSrc);
        args.put("flashVer", "10");
        args.put("flashVars", flashVars);
        return (FlashContainer) Executions.createComponents(
            FlashContainer.ZUL_PATH, parent, args);
    }
    
    /**
     * 构造器.
     */
    public FlashContainer() {
        this.ns = this.getUuid();
        this.appendChild(this.eventListener);
        this.appendChild(this.flash);
        this.appendChild(this.script);
        
        this.eventListener.addEventListener(FlashContainer.ON_CIENT_INFO,
            new EventListener() {
                @Override
                public void onEvent(Event event) throws Exception {
                    // flash 控件不支持,打开下载页面
                    if (event.getData().equals("flashNotSupported")) {
                        alert("flashNotSupported");
                    }
                    
                    for (Component comp : FlashContainer.this.observers) {
                        
                        Event e = new Event(FlashContainer.ON_CONTAINER_INFO,
                            comp, event.getData());
                        Events.sendEvent(e);
                    }
                }
            });
        
        // 发送事件脚本
        String scriptStr = "function " + this.ns
            + "_flashSend(v){var e = new zk.Event();e.$init(zk.Widget.$('"
            + this.eventListener.getUuid() + "'), '"
            + FlashContainer.ON_CIENT_INFO + "', v);zAu.send(e);}";
        
        // 调用 flash 方法
        scriptStr += "function " + this.ns + "_callFlash(jsonStr){"
            + "var flash=null;try{flash = document.getElementById(\""
            + this.flash.getUuid()
            + "\").jsCall(jsonStr);}catch(err){setTimeout(\"" + this.ns
            + "_callFlash('\"+jsonStr+\"')\",150);}}";
        
        this.script.setContent(scriptStr);
        
        // swfobject
        Script swfobject = new Script();
        swfobject.setSrc("/common/js/swfobject.js");
        this.appendChild(swfobject);
        
    }
    
    /*
     * @see org.zkoss.zk.ui.ext.AfterCompose#afterCompose()
     */
    @SuppressWarnings("unchecked")
    @Override
    public void afterCompose() {
        // javaScript 可识别的 swf 地址
        String flashSrc = (String) Executions.getCurrent().getArg()
            .get("flashSrc");
        
        // flash 播放需要的播放器版本号
        String flashVer = (String) Executions.getCurrent().getArg()
            .get("flashVer");
        
        // 传递给 flash 的参数
        Map<String, String> flashVars = (Map<String, String>) Executions
            .getCurrent().getArg().get("flashVars");
        
        String detectFlashVer = "9,0,124";
        String swfobjectFlashVer = "9.0.124";
        if (flashVer != null && flashVer.equals("10")) {
            detectFlashVer = "10,0,0";
            swfobjectFlashVer = "10.0.0";
        }
        
        // 检查 flash 控件版本,若不支持给定的 flash 版本,弹出页面
        Clients.evalJavaScript("if(!DetectFlashVer(" + detectFlashVer + ")){"
            + this.ns + "_flashSend('flashNotSupported');}");
        
        // 初始化flash,传入 js发送事件方法名
        Clients.evalJavaScript("function " + this.ns
            + "_initSWF(){try{swfobject.embedSWF('" + flashSrc + "', '"
            + this.flash.getUuid() + "', '100%', '100%', '" + swfobjectFlashVer
            + "', '', {eventFunc:'" + this.ns + "_flashSend'"
            + this.genFlashVars(flashVars)
            + "}, {wmode:'opaque'}, {});}catch(e){setTimeout('" + this.ns
            + "_initSWF();',100);}}" + this.ns + "_initSWF();");
        
    }
    
    /**
     * 生成 flashvars 参数字串.<br/>
     * 若参数为 null,则生成的参数为 ''<br/>
     * 参数名为空的参数将被忽略;含有引号的参数为非法参数,将抛运行时异常<br/>
     * 格式:,a:'a',b:'b'
     * 
     * @param flashVars
     *            参数 map
     * @return 参数字串
     */
    private String genFlashVars(Map<String, String> flashVars) {
        if (flashVars == null) {
            return "";
        }
        
        StringBuilder vars = new StringBuilder("");
        
        String tempKey, tempValue;
        for (Map.Entry<String, String> entry : flashVars.entrySet()) {
            tempKey = entry.getKey();
            if (tempKey == null || tempKey.length() == 0) {
                continue;
            }
            tempValue = entry.getValue();
            if (tempValue == null || tempValue.contains("\'")
                || tempValue.contains("\"")) {
                throw new RuntimeException("非法参数:" + tempValue);
            }
            
            vars.append(",");
            vars.append(tempKey);
            vars.append(":'");
            vars.append(tempValue);
            vars.append("'");
        }
        return vars.toString();
    }
    
    /**
     * 只执行最新的调用(以调用顺序为准),忽略旧的调用(执行顺序值小于客户端当前执行顺序值的调用). <br/>
     * 此方法用于解决对 flash 端的多个调用不能保证顺序的问题. <br/>
     * 若不希望任何调用被忽略,请用 callFlashFuncList 方法. <br/>
     * 调用flash方法.
     * 
     * @param func
     *            flash 方法名
     * @param args
     *            可变参数(参数中不允许含有 &quot; 或 &apos;,有则抛异常)
     */
    public void callFlashLatest(String func, String... args) {
        this.innerCallFlashFuncList(this.orderGen.incrementAndGet(),
            FlashFuncInvoke.genSingleEleList(func, args));
    }
    
    /**
     * 调用flash方法. 这个方法的多个调用在 flash 客户端不能保证调用顺序. <br/>
     * 要确保调用顺序,尝试 callFlashLatest 或 callFlashFuncList 方法. <br/>
     * 
     * @param func
     *            flash 方法名
     * @param args
     *            可变参数(参数中不允许含有 &quot; 或 &apos;,有则抛异常)
     */
    public void callFlash(String func, String... args) {
        this.innerCallFlashFuncList(-1L,
            FlashFuncInvoke.genSingleEleList(func, args));
    }
    
    /**
     * 只执行最新的调用(以调用顺序为准),忽略旧的调用(执行顺序值小于客户端当前执行顺序值的调用). <br/>
     * 此方法用于解决对 flash 端的多个调用不能保证顺序的问题. <br/>
     * 按顺序执行给定的 flash 方法. <br/>
     * 方法参数中不允许含有 &quot; 或 &apos;,有则抛异常
     * 
     * @param list
     *            方法定义列表
     */
    public void callFlashFuncListLatest(List<FlashFuncInvoke> list) {
        this.innerCallFlashFuncList(this.orderGen.incrementAndGet(), list);
    }
    
    /**
     * 按顺序执行给定的 flash 方法. 这个方法的多个调用在 flash 客户端不能保证调用顺序. <br/>
     * 要确保调用顺序,尝试 callFlashFuncListLatest 方法. <br/>
     * 方法参数中不允许含有 &quot; 或 &apos;,有则抛异常
     * 
     * @param list
     *            方法定义列表
     */
    public void callFlashFuncList(List<FlashFuncInvoke> list) {
        this.innerCallFlashFuncList(-1L, list);
    }
    
    /**
     * 向 flash 客户端发送执行命令(方法调用).
     * 
     * @param order
     *            给定一个执行顺序值(一个从小到大的正值,不能大于 2^52-1=4503599627370495L. <br/>
     *            若为 -1L,则 flash 端执行此调用;若为一个正值,则 flash
     *            端将忽略旧的调用(执行顺序值小于客户端当前执行顺序值的调用). <br/>
     *            给定执行顺序值用于解决这样一个问题:flash 客户端的多个调用的执行不能同步,但给定执行顺序将导致旧的调用被忽略
     * @param list
     *            方法定义列表
     */
    private void innerCallFlashFuncList(long order, List<FlashFuncInvoke> list) {
        if (order < -1L || order > FlashContainer.ORDER_LIMIT) {
            throw new RuntimeException("执行顺序值超出 [-1, 2^52-1]");
        }
        
        if (list == null || list.size() < 1) {
            return;
        }
        
        StringBuilder str = new StringBuilder("var j={order:");
        str.append(order);
        str.append(",funcs:[");
        for (FlashFuncInvoke funcInvoke : list) {
            str.append(this.genJsonString(funcInvoke.func, funcInvoke.args));
            str.append(",");
        }
        if (str.charAt(str.length() - 1) == ',') {
            str.deleteCharAt(str.length() - 1);
        }
        str.append("]}");
        
        Clients.evalJavaScript(this.ns + "_callFlash(\'" + str.toString()
            + "\')");
    }
    
    /**
     * 根据给定的方法名、方法参数生成 json 对象字符串.
     * 
     * @param func
     *            方法名
     * @param args
     *            方法参数(参数中不允许含有 &quot; 或 &apos;,有则抛异常)
     * @return json 对象字符串
     */
    private String genJsonString(String func, String[] args) {
        String argsStr = "";
        if (args != null && args.length != 0) {
            for (String arg : args) {
                if (arg == null) {
                    throw new RuntimeException("不允许 null 值作为参数");
                }
                if (arg.contains("&quot;") || arg.contains("&apos;")) {
                    throw new RuntimeException("参数中不允许含有 &quot; 或 &apos;");
                }
                argsStr += "\""
                    + arg.replace("\"", "&quot;").replace("'", "&apos;")
                    + "\",";
            }
            argsStr = argsStr.substring(0, argsStr.length() - 1);
        }
        return "{func:\"" + func + "\", args:[" + argsStr + "]}";
    }
    
    /**
     * 注册一个 flash 事件观察者.
     * 该观察者需要注册 ON_CONTAINER_INFO 的事件监听
     * 
     * @param observer
     *            flash 动作观察者
     */
    public void registObserver(Component observer) {
        this.observers.add(observer);
    }
    
}
 

 

0
0
分享到:
评论
2 楼 maofan3000 2013-08-12  
不知道swfobject需要下载什么版本?
1 楼 maofan3000 2013-08-12  
我拿你的例子,怎么也不出效果,您能把你的文件打包下载吗?

相关推荐

    SMC ZK2-ZSEA-A设置方法

    ### SMC ZK2-ZSEA-A 设置方法详解 #### 一、产品概述 SMC ZK2-ZSEA-A是一款带有节能功能的真空发生器,它采用数字式压力开关技术,适用于各种工业自动化应用场景。该型号的产品能够有效提高真空系统的效率,并具备...

    Zkteco中控智慧雷达探测器ZK-RD01-79用户手册.pdf

    中控智慧设备说明书

    zk-bin-5.0.0-RC.zip_DEMO_fckez.jar_zk_zk demo_zk-demo-5.0.z

    其中包含了一个名为`fckez.jar`的应用程序,以及与Zookeeper(zk)相关的示例代码或应用,可能是`zk_demo`或`zk-demo-5.0.z`。这个压缩包很可能是用于帮助开发者理解和学习如何在实际环境中部署和使用Zookeeper。 ...

    zk-src-6.0.1.zip_zk_zk java_zk-src-6.5.1.1

    标签"zk"、"zk_java"、"zk-src-6.5.1.1"进一步强调了这是与ZK框架、Java语言以及特定版本6.5.1.1相关的知识。ZK框架是用Java编写的,因此它完全兼容Java平台,并且可以与其他Java技术如Spring、Hibernate等无缝集成...

    幸福象花一样 ZKZK REMIX_2---02.flp

    幸福象花一样 ZKZK REMIX_2---02.flp

    zk-zss-bin-1.0.0-RC2.zip_zk_zk zss_zk-zss-bin

    标题中的"zk-zss-bin-1.0.0-RC2.zip"是一个关于Zookeeper的软件包,其中"zk"代表Zookeeper,"zss"可能是Zookeeper Server Statistics的缩写,而"bin"通常指的是可执行文件或二进制文件的目录。"1.0.0-RC2"是版本号,...

    ZK Spreadsheet(3-1)

    ZK Spreadsheet(3-1)

    zk-bin-3.6.2.zip_zk_zk version 3_zk-bin-5.0.2

    【标题】"zk-bin-3.6.2.zip_zk_zk version 3_zk-bin-5.0.2" 涉及到的是ZooKeeper的两个不同版本,即3.6.2和5.0.2。ZooKeeper是一个分布式协调服务,广泛应用于大数据和分布式计算系统中,如Hadoop、HBase等。它提供...

    zk-bin-6.5.0.zip

    zk-6.5.0.zip ZK 6.5.0 Sep 12, 2012 * Features ZK-447: The file upload allows users to drag and drop local files (HTML5) ZK-1241: ZK Client Widget support swipe event for tablet/mobile device ZK-...

    ZK剂量仪系列-ermes-electronics.pdf

    ZK剂量仪系列-ermes-electronics.pdf

    ZK Spreadsheet(3-3)

    4. **学习ZK API**:理解Java或其他语言的ZooKeeper客户端API,学习如何在代码中与ZooKeeper交互。 5. **实战演练**:通过编写简单的应用程序,实践分布式协调服务的使用,比如实现一个简单的分布式锁。 通过这个...

    ZK-quickstart-3.0.0-cn快速入门中文版

    如果需要更多的组件和功能,则应考虑 `zk-bin-prof-3.0.0.tar.gz` 或 `zk-bin-3.0.0.tar.gz`。 #### 翻译说明与 Bug 列表 在翻译过程中,发现了一些文档中的错误和不一致的地方。以下是已知的问题列表: - `dist\...

    zk-bin-7.0.2.zip

    总的来说,"zk-bin-7.0.2.zip"是一个用于构建富客户端Web应用的ZK框架二进制包,它提供了丰富的UI组件和数据可视化功能,适用于需要交互式用户界面和图表展示的项目。通过学习和使用ZK,开发者可以更高效地开发出...

    zk-bin-std-3.0.1

    "zk-bin-std-3.0.1" 是一个与ZK框架相关的软件包,它包含ZK框架的标准版本3.0.1的所有组件。ZK是一个基于Java的客户端服务器端架构的用户界面(UI)开发框架,尤其适用于构建富互联网应用程序(RIA)。它的主要特点...

    zk-bin-6.5.3.zip

    在本压缩包"zk-bin-6.5.3.zip"中,包含的是ZK的最新版本6.5.3的二进制发行版。 在ZK的开发过程中,开发者通常会依赖ZK提供的jar包来构建和运行分布式应用。这些jar包包含了ZK的客户端和服务端的所有必需组件,使得...

    TPC-ZK-II集成开发环境

    TPC-ZK-II微机接口实验系统正是在这种背景下推出的,该设备在TPC-ZK-II微机接口实验系统上配置了USB接口模块,直接与主机(PC)的USB接口连接,形成了一套完整的USB总线接口的微机接口实验系统。

    zk-Gmaps-src-2.0_10.zip

    zk-Gmaps-src-2.0_10.zip zk-Gmaps-src-2.0_10.zip

    zk扩展工具--spring集成--字符串处理--日期处理

    这个模块提供了与ZooKeeper进行交互的API,允许我们在Spring应用中方便地使用ZooKeeper的服务发现、配置管理等功能。为了集成Zookeeper,我们需要在Spring Boot的`pom.xml`文件中引入相应的依赖,并配置Zookeeper的...

    wxh zk-src-3.0.3-2008-01-31

    标题中的“wxh zk-src-3.0.3-2008-01-31”似乎是指一个名为“zk-src”的项目或软件的版本信息,版本号为3.0.3,发布日期为2008年1月31日。这个“wxh”可能是个人或团队的名字,也可能是项目的一部分标识。描述和标签...

Global site tag (gtag.js) - Google Analytics