- 浏览: 94795 次
- 性别:
- 来自: 广州
最新评论
-
wmx11:
melody_hu 写道请问下收到消息后的处理代码是修改的哪一 ...
XMPP实现群聊截图(spark+openfire) -
wanggang0321:
你的spark的客户端界面是如何开发的?我用的eclipse ...
spark二次开发之客户端工具栏 -
melody_hu:
请问下收到消息后的处理代码是修改的哪一地方的源码?可以把实现发 ...
XMPP实现群聊截图(spark+openfire) -
wll52:
有问题在 linux下失效URL oUrl=new URL(s ...
openfire如何获取所有在线用户 -
zzandww:
hi,请教一下这个群是怎么搞的?自己开发的?
XMPP实现群聊截图(spark+openfire)
spark二次开发之客户端工具栏
- 博客分类:
- IM
最近一段时间因为工作关系,可能会整理一些spark二次开发的细节问题。
客户端工具栏,可以在客户端上添加各种系统的集成,一些小功能实现的快捷方式。
具体修改类为workspace.java
具体代码如下:
* $RCSfile: ,v $ package org.jivesoftware.spark; import java.awt.BorderLayout; /** * The inner Container for Spark. The Workspace is the container for all plugins * into the Spark install. Plugins would use this for the following: * <p/> * <ul> * <li>Add own tab to the main tabbed pane. ex. * <p/> * <p/> * Workspace workspace = SparkManager.getWorkspace(); JButton button = new * JButton("HELLO SPARK USERS"); workspace.getWorkspacePane().addTab("MyPlugin", * button); * </p> * <p/> * <li>Retrieve the ContactList. description: 即时通讯面板空间 * * @author e40 * @project_name Lyim * @version v1.0 * @createTime 2011-6-1 下午03:36:21 */ public class Workspace extends JPanel implements PacketListener { private static final long serialVersionUID = 7076407890063933765L; private SparkTabbedPane workspacePane; private StatusBar statusBox; private CommandPanel toolPanel; // 扩展工具栏 private ContactList contactList; private ConferenceServices conferences; private GatewayPlugin gatewayPlugin; private BookmarkPlugin bookmarkPlugin; private ChatTranscriptPlugin transcriptPlugin; private BroadcastPlugin broadcastPlugin; private ScratchPadPlugin scratchPadPlugin; private static Workspace singleton; private static final Object LOCK = new Object(); private JPanel cardPanel; private CardLayout cardLayout; public static final String WORKSPACE_PANE = "WORKSPACE_PANE"; private final RolloverButton message_btn; private final RolloverButton loginPortal_btn; private final RolloverButton openLyimBrowser_btn; private RolloverButton mail_btn=new RolloverButton( SparkRes.getImageIcon(SparkRes.MESSAGE_NOTICE_IMAGE));; private final RolloverButton broadcast_btn; private final RolloverButton task_btn; private String mail_CallbackStr = ""; private static boolean alert_msg = true; private final RolloverButton notes_btn = new RolloverButton( SparkRes.getImageIcon(SparkRes.DOCUMENT_16x16)); /** * Returns the singleton instance of <CODE>Workspace</CODE>, creating it if * necessary. * <p/> * * @return the singleton instance of <Code>Workspace</CODE> */ public static Workspace getInstance() { // Synchronize on LOCK to ensure that we don't end up creating // two singletons. synchronized (LOCK) { if (null == singleton) { Workspace controller = new Workspace(); singleton = controller; return controller; } } return singleton; } /** * Creates the instance of the SupportChatWorkspace. */ private Workspace() { final MainWindow mainWindow = SparkManager.getMainWindow(); // Add MainWindow listener mainWindow.addMainWindowListener(new MainWindowListener() { public void shutdown() { final ChatContainer container = SparkManager.getChatManager() .getChatContainer(); // Close all Chats. for (ChatRoom chatRoom : container.getChatRooms()) { // Leave ChatRoom container.leaveChatRoom(chatRoom); } conferences.shutdown(); gatewayPlugin.shutdown(); bookmarkPlugin.shutdown(); broadcastPlugin.shutdown(); } public void mainWindowActivated() { } public void mainWindowDeactivated() { } }); // Initialize workspace pane, defaulting the tabs to the bottom. workspacePane = new SparkTabbedPane(JTabbedPane.BOTTOM); workspacePane.setBorder(BorderFactory.createEmptyBorder()); // Add Panels. cardLayout = new CardLayout(); cardPanel = new JPanel(cardLayout); cardPanel.setOpaque(false); cardPanel.add(WORKSPACE_PANE, this); statusBox = new StatusBar(); toolPanel = new CommandPanel(); if(!Default.getBoolean("MAIL_DISABLE")){ mail_CallbackStr = MailUtils.getCallbackStr(); if (mail_CallbackStr.equals("?") && alert_msg) { alert_msg = false; int key = JOptionPane.showConfirmDialog(this, "邮箱绑定错误,是否重新绑定?", "邮箱错误", JOptionPane.OK_CANCEL_OPTION); if (key == JOptionPane.OK_OPTION) { try { BrowserLauncher.openSystem(SparkRes .getString(SparkRes.MAIL_URL)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } mail_btn = new RolloverButton( SparkRes.getImageIcon(SparkRes.MESSAGE_NOTICE_IMAGE)); mail_btn.setToolTipText("绑定邮箱错误"); } else if (mail_CallbackStr.equals("No_Buddy") && alert_msg) { alert_msg = false; int reply = JOptionPane.showConfirmDialog(this, "未绑定邮箱,请先到门户绑定邮箱", "绑定邮箱", JOptionPane.OK_CANCEL_OPTION); if (reply == JOptionPane.OK_OPTION) { try { BrowserLauncher.openSystem(SparkRes .getString(SparkRes.MAIL_URL)); } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } mail_btn = new RolloverButton( SparkRes.getImageIcon(SparkRes.MESSAGE_NOTICE_IMAGE)); mail_btn.setToolTipText("未绑定邮箱"); } else if (mail_CallbackStr.equals("error") && alert_msg) { alert_msg = false; JOptionPane.showMessageDialog(this, "邮件服务器配置错误!", "邮箱错误", JOptionPane.CLOSED_OPTION); mail_btn = new RolloverButton( SparkRes.getImageIcon(SparkRes.MESSAGE_NOTICE_IMAGE)); mail_btn.setToolTipText("邮件服务器配置错误"); } else { mail_btn = new RolloverButton(mail_CallbackStr, SparkRes.getImageIcon(SparkRes.MESSAGE_NOTICE_IMAGE)); mail_btn.setToolTipText("未读邮件:" + mail_CallbackStr); } //如果要屏蔽邮件,此处需修改 // toolPanel.add(mail_btn); mail_btn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { BrowserLauncher.openSystem(SparkRes .getString(SparkRes.MAIL_URL)); } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } }); } message_btn = new RolloverButton( SparkRes.getImageIcon(SparkRes.MESSAGE_BOX_IMAGE)); loginPortal_btn = new RolloverButton( SparkRes.getImageIcon(SparkRes.PORTAL_LOGIN_IMAGE)); openLyimBrowser_btn = new RolloverButton( SparkRes.getImageIcon(SparkRes.MESSAGE_VIEW_IMAGE)); broadcast_btn = new RolloverButton( SparkRes.getImageIcon(SparkRes.MEGAPHONE_16x16)); task_btn = new RolloverButton( SparkRes.getImageIcon(SparkRes.DESKTOP_IMAGE)); toolPanel.add(loginPortal_btn); //如果不配置邮件,此处需修改 // toolPanel.add(mail_btn); if (!Default.getBoolean("BROWSER_DISABLE")) { toolPanel.add(openLyimBrowser_btn); } toolPanel.add(broadcast_btn); toolPanel.add(message_btn); toolPanel.add(task_btn); toolPanel.add(notes_btn); loginPortal_btn.setToolTipText("登录门户系统"); message_btn.setToolTipText("查看消息公告"); openLyimBrowser_btn.setToolTipText("我的资讯"); broadcast_btn.setToolTipText("广播消息"); task_btn.setToolTipText("查看任务列表"); notes_btn.setToolTipText("查看记事本"); task_btn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { scratchPadPlugin.getTask(); } }); notes_btn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { scratchPadPlugin.getNotes(); } }); // duanwu by hc loginPortal_btn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { String url = SparkRes.getString(SparkRes.TARGET_URL); BrowserLauncher.openSystem(url); } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } }); message_btn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { new MessageBox().invokeDialog(); } }); broadcast_btn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { broadcastToRoster(); } private void broadcastToRoster() { final BroadcastDialog broadcastDialog = new BroadcastDialog(); broadcastDialog.invokeDialog(); } }); openLyimBrowser_btn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { EmbeddedBrowserViewer viewer = new EmbeddedBrowserViewer(); viewer.initializeBrowser(); JFrame frame = new JFrame(); frame.setFont(new Font("微软雅黑", Font.PLAIN, 13)); frame.setIconImage(SparkRes.getImageIcon( SparkRes.MESSAGE_VIEW_IMAGE).getImage()); frame.getContentPane().setLayout(new BorderLayout()); frame.getContentPane().add(viewer, BorderLayout.CENTER); frame.setVisible(true); frame.pack(); frame.setSize(600, 400); // final ClassLoader cl = SparkRes.class.getClassLoader(); // viewer.loadURL(cl.getResource("web/package.html").toString()); String default_infor_url = Default .getString(Default.MY_INFORMATION); viewer.loadURL(default_infor_url); frame.setResizable(false); } }); // final TimerTask task = new SwingTimerTask() { // public void doRun() { // String mail_CallbackStr = "0"; // mail_CallbackStr = MailUtils.getCallbackStr(); // // mail_btn.setText(mail_CallbackStr + ""); // if (mail_CallbackStr.equals("error")) { // mail_btn.setToolTipText("邮件服务器配置错误"); // } else if (mail_CallbackStr.equals("error")) { // mail_btn.setToolTipText("邮件绑定错误"); // } else { // mail_btn.setText(mail_CallbackStr); // mail_btn.setToolTipText("未读邮件数:" + mail_CallbackStr); // } // } // }; // TaskEngine.getInstance() // .schedule( // task, // Integer.parseInt(Default // .getString(Default.DEFAULT_EMAIL_TIME)) * 1000); // Build default workspace this.setLayout(new GridBagLayout()); add(workspacePane, new GridBagConstraints(0, 9, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); add(statusBox, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); add(toolPanel, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(1, 0, 1, 0), 0, 0)); this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( KeyStroke.getKeyStroke("F12"), "showDebugger"); this.getActionMap().put("showDebugger", new AbstractAction("showDebugger") { private static final long serialVersionUID = 4066886679016416923L; public void actionPerformed(ActionEvent evt) { EnhancedDebuggerWindow window = EnhancedDebuggerWindow .getInstance(); window.setVisible(true); } }); // Set background setBackground(new Color(235, 239, 254)); } /** * Builds the Workspace layout. */ public void buildLayout() { new Enterprise(); // Initialize Contact List contactList = new ContactList(); conferences = new ConferenceServices(); // Init contact list. contactList.initialize(); // Load VCard information for status box statusBox.loadVCard(); // Initialise TransferManager SparkTransferManager.getInstance(); } /** * Starts the Loading of all Spark Plugins. */ public void loadPlugins() { // Add presence and message listeners // we listen for these to force open a 1-1 peer chat window from other // operators if // one isn't already open PacketFilter workspaceMessageFilter = new PacketTypeFilter( Message.class); // Add the packetListener to this instance SparkManager.getSessionManager().getConnection() .addPacketListener(this, workspaceMessageFilter); // Make presence available to anonymous requests, if from anonymous user // in the system. PacketListener workspacePresenceListener = new PacketListener() { public void processPacket(Packet packet) { Presence presence = (Presence) packet; if (presence.getProperty("anonymous") != null) { boolean isAvailable = statusBox.getPresence().getMode() == Presence.Mode.available; Presence reply = new Presence(Presence.Type.available); if (!isAvailable) { reply.setType(Presence.Type.unavailable); } reply.setTo(presence.getFrom()); SparkManager.getSessionManager().getConnection() .sendPacket(reply); } } }; SparkManager .getSessionManager() .getConnection() .addPacketListener(workspacePresenceListener, new PacketTypeFilter(Presence.class)); // Send Available status final Presence presence = SparkManager.getWorkspace().getStatusBar() .getPresence(); SparkManager.getSessionManager().changePresence(presence); // Until we have better plugin management, will init after presence // updates. gatewayPlugin = new GatewayPlugin(); gatewayPlugin.initialize(); // Load all non-presence related items. conferences.loadConferenceBookmarks(); SearchManager.getInstance(); transcriptPlugin = new ChatTranscriptPlugin(); // Load Broadcast Plugin broadcastPlugin = new BroadcastPlugin(); broadcastPlugin.initialize(); // Load BookmarkPlugin bookmarkPlugin = new BookmarkPlugin(); bookmarkPlugin.initialize(); // Load scratchPadPlugin scratchPadPlugin = new ScratchPadPlugin(); // Schedule loading of the plugins after two seconds. TaskEngine.getInstance().schedule(new TimerTask() { public void run() { final PluginManager pluginManager = PluginManager.getInstance(); SparkManager.getMainWindow().addMainWindowListener( pluginManager); pluginManager.initializePlugins(); // Subscriptions are always manual Roster roster = SparkManager.getConnection().getRoster(); roster.setSubscriptionMode(Roster.SubscriptionMode.manual); } }, 2000); // Check URI Mappings SparkManager.getChatManager().handleURIMapping(Spark.ARGUMENTS); } /** * Returns the status box for the User. * * @return the status box for the user. */ public StatusBar getStatusBar() { return statusBox; } /** * This is to handle agent to agent conversations. * * @param packet * the smack packet to process. */ public void processPacket(final Packet packet) { SwingUtilities.invokeLater(new Runnable() { public void run() { handleIncomingPacket(packet); } }); } private void handleIncomingPacket(Packet packet) { // We only handle message packets here. if (packet instanceof Message) { final Message message = (Message) packet; boolean isGroupChat = message.getType() == Message.Type.groupchat; // Check if Conference invite. If so, do not handle here. if (message.getExtension("x", "jabber:x:conference") != null) { return; } final String body = message.getBody(); boolean broadcast = message.getProperty("broadcast") != null; if (Message.Type.normal == message.getType()) { String from = message.getFrom(); from = from.substring(0, from.indexOf("@")); String defaultSender=Default.getString("DEFAULT_MESSAGE_SENDER"); if (defaultSender.equalsIgnoreCase(from)) { MessageBean ntb = new MessageBean(); String source = (String) message.getProperty("source"); String sourceId = (String) message.getProperty("sourceId"); String subject = message.getSubject(); String content = message.getBody(); String sendTime = (String) message.getProperty("sendTime"); String url = (String) message.getProperty("url"); ntb.setSource(source); ntb.setSourceId(sourceId); ntb.setSubject(subject); ntb.setContent(content); ntb.setIsread(MessageConstant.UNREAD);// 0代表未讀 ntb.setSendTime(sendTime); ntb.setUrl(url); HandleXML hand = new HandleXML(); ntb = SecritHelper.encode(ntb); hand.addNewNode(ntb); SparkToaster toaster = new SparkToaster(); toaster.showToaster( "主题:" + message.getSubject() + "\n\n 消息来源:" + source + "\n\n\n 发送时间:" + sendTime, url); } } // Handle offline message. DelayInformation offlineInformation = (DelayInformation) message .getExtension("x", "jabber:x:delay"); if (offlineInformation != null && (Message.Type.chat == message.getType() || Message.Type.normal == message .getType())) { handleOfflineMessage(message); } if (body == null || isGroupChat || broadcast || message.getType() == Message.Type.normal || message.getType() == Message.Type.headline || message.getType() == Message.Type.error) { return; } // Create new chat room for Agent Invite. final String from = packet.getFrom(); final String host = SparkManager.getSessionManager() .getServerAddress(); // Don't allow workgroup notifications to come through here. final String bareJID = StringUtils.parseBareAddress(from); if (host.equalsIgnoreCase(from) || from == null) { return; } ChatRoom room = null; try { room = SparkManager.getChatManager().getChatContainer() .getChatRoom(bareJID); } catch (ChatRoomNotFoundException e) { // Ignore } // Check for non-existent rooms. if (room == null) { createOneToOneRoom(bareJID, message); } } } /** * Creates a new room if necessary and inserts an offline message. * * @param message * The Offline message. */ private void handleOfflineMessage(Message message) { if (!ModelUtil.hasLength(message.getBody()) || message.getFrom().contains("admin")) { return; } String bareJID = StringUtils.parseBareAddress(message.getFrom()); ContactItem contact = contactList.getContactItemByJID(bareJID); String nickname = StringUtils.parseName(bareJID); if (contact != null) { nickname = contact.getDisplayName(); } // Create the room if it does not exist. ChatRoom room = SparkManager.getChatManager().createChatRoom(bareJID, nickname, nickname); if (!SparkManager.getChatManager().getChatContainer().getChatFrame() .isVisible()) { SparkManager.getChatManager().getChatContainer().getChatFrame() .setVisible(true); } // Insert offline message room.getTranscriptWindow().insertMessage(nickname, message, ChatManager.FROM_COLOR, Color.white); room.addToTranscript(message, true); // Send display and notified message back. SparkManager.getMessageEventManager().sendDeliveredNotification( message.getFrom(), message.getPacketID()); SparkManager.getMessageEventManager().sendDisplayedNotification( message.getFrom(), message.getPacketID()); } /** * Creates a new room based on an anonymous user. * * @param bareJID * the bareJID of the anonymous user. * @param message * the message from the anonymous user. */ private void createOneToOneRoom(String bareJID, Message message) { ContactItem contact = contactList.getContactItemByJID(bareJID); String nickname = StringUtils.parseName(bareJID); if (contact != null) { nickname = contact.getDisplayName(); } else { // Attempt to load VCard from users who we are not subscribed to. VCard vCard = SparkManager.getVCardManager().getVCard(bareJID); if (vCard != null && vCard.getError() == null) { String firstName = vCard.getFirstName(); String lastName = vCard.getLastName(); String userNickname = vCard.getNickName(); if (ModelUtil.hasLength(userNickname)) { nickname = userNickname; } else if (ModelUtil.hasLength(firstName) && ModelUtil.hasLength(lastName)) { nickname = firstName + " " + lastName; } else if (ModelUtil.hasLength(firstName)) { nickname = firstName; } } } SparkManager.getChatManager().createChatRoom(bareJID, nickname, nickname); try { insertMessage(bareJID, message); } catch (ChatRoomNotFoundException e) { Log.error("Could not find chat room.", e); } } private void insertMessage(final String bareJID, final Message message) throws ChatRoomNotFoundException { ChatRoom chatRoom = SparkManager.getChatManager().getChatContainer() .getChatRoom(bareJID); chatRoom.insertMessage(message); int chatLength = chatRoom.getTranscriptWindow().getDocument() .getLength(); chatRoom.getTranscriptWindow().setCaretPosition(chatLength); chatRoom.getChatInputEditor().requestFocusInWindow(); } /** * Returns the Workspace TabbedPane. If you wish to add your component, * simply use addTab( name, icon, component ) call. * * @return the workspace JideTabbedPane */ public SparkTabbedPane getWorkspacePane() { return workspacePane; } /** * Returns the <code>ContactList</code> associated with this workspace. * * @return the ContactList associated with this workspace. */ public ContactList getContactList() { return contactList; } public void changeCardLayout(String layout) { cardLayout.show(cardPanel, layout); } public JPanel getCardPanel() { return cardPanel; } /** * Returns the <code>CommandPanel</code> of this Workspace. * * @return the CommandPanel. */ public CommandPanel getCommandPanel() { return statusBox.getCommandPanel(); } public ChatTranscriptPlugin getTranscriptPlugin() { return transcriptPlugin; } /** * * description: 获取工具栏面板 * * @author e40 * @project_name Lyim * @class_name Workspace.java * @version v1.0 * @createTime 2011-6-1 下午05:24:06 CommandPanel * @return */ public CommandPanel getToolPanel() { return toolPanel; } }
效果图如下:
可以集成门户,邮件系统等(部分中文未使用国际化,方便阅读)
评论
1 楼
wanggang0321
2016-07-21
你的spark的客户端界面是如何开发的?
我用的eclipse juno,安装了windows builder插件,但是不能打开spark的界面,打开后是下面的样子:
,
现在还在寻求解决方案
我用的eclipse juno,安装了windows builder插件,但是不能打开spark的界面,打开后是下面的样子:
,
现在还在寻求解决方案
发表评论
-
XMPP协议相关
2011-11-08 21:13 5112务器下的客户端也可以通信,XMPP的前身是一个开源组织制 ... -
spark二次开发会议列表乱码解决思路
2011-10-25 16:34 2217修改BookMarkItem.java中 pu ... -
spark二次开发之客户端实名制实现
2011-10-20 13:54 1905服务端openfire数据可以通过LDAP来同步已经存在的完整 ... -
spark二次开发之广播消息(针对群用户)的实现
2011-09-14 16:47 2141代码如下 try { gr ... -
XMPP群聊截图后在历史消息中显示图片
2011-08-31 14:44 2196截图后保存到xml中是用图片的信息来进行保存的,只需要通过图片 ... -
XMPP实现群聊截图(spark+openfire)
2011-08-31 09:55 12685spark默认的单聊截图模式是利用文件来来进行传递,调用Spa ... -
openfire如何获取所有在线用户
2011-08-15 17:08 17022想象中如此简单的功能 ...
相关推荐
1. 下载客户端登录FusionInsight HD spark下载客户端工具安装包。 2. 获取样例工程解压客户端包,从中获取Sample样例工程。 3. 执行安装目录中的install.bat生成工程。 4. 导入Idea将样例工程导入到Idea中,并同时...
总之,Spark-2作为一款可二次开发的聊天客户端,为企业提供了一种高效、灵活的沟通工具。通过深入理解和定制化开发,可以打造符合自身业务需求的即时通讯解决方案。同时,结合Openfire的强大服务器支持,能够构建出...
《Spark最新源码与二次开发详解》 Spark作为一款开源的大数据处理框架,因其高效、易用和灵活性而备受开发者青睐。在Openfire环境中,Spark更扮演着关键的角色,为实时通讯提供支持。本教程旨在深入解析Spark的最新...
二次开发通常包括自定义转换操作、优化Spark应用程序性能、开发Spark Shell工具或与外部系统集成。 2. **HBase二次开发**:HBase是一个基于Hadoop的分布式列族数据库,适用于大数据实时读写场景。二次开发可能涉及...
docker-spark, 通用 Apache Spark 客户端的Docker 映像 客户端 Docker 映像 这个存储库包含一个运行的 Docker 映像。要运行简单的spark shell 插件,请执行以下操作:docker run -it epahomov/docker-spark:lightwe
《Spark+Openfire二次开发(三):深入理解与实践》 在IT行业中,Spark和Openfire是两个非常重要的开源工具,它们分别在大数据处理和即时通讯领域有着广泛的应用。本篇文章将深入探讨如何对这两者进行二次开发,...
Spark+Openfire 二次开发需要掌握 Java 语言、Eclipse 开发环境、Ant 工具、XMPP 协议等技术。同时,需要了解 Spark 和 Openfire 的架构和原理,才能更好地进行二次开发。 知识点: 1. Spark 和 Openfire 的架构和...
在Spark的二次开发过程中,经常会遇到需要对源码进行修改或扩展以满足特定需求的情况。在这样的场景下,正确配置和构建环境至关重要。标题提到的"spark 二次开发所需缺失3jar包"揭示了在搭建Spark源码工程时,有三个...
富客户端spark2.8.3_windows,在国内从官网的下载速度极慢,有需要的朋友,可以从这里下载
"openfire + spark 开发" 在本文中,我们将讨论基于 Openfire 和 Spark 的 XMPP IM 软件开发。我们将从 XMPP 协议的介绍开始,接着讨论如何使用 Spark 和 Openfire 来实现一个完整的 IM 软件开发。 什么是 XMPP? ...
flex sparkweb 客户端输入服务器地址、用户名和密码可登录openfire
二次开发主要涉及对Spark客户端及Openfire服务器的功能扩展和定制化修改。 1. **界面自定义**:根据需求修改Spark客户端的用户界面,如添加新的功能按钮或调整布局样式。 2. **功能扩展**:例如实现消息加密传输、...
【Openfire、Spark和SparkWeb】是一套开源的即时通讯解决方案,主要由Openfire服务器、Spark客户端和SparkWeb网页客户端组成。Openfire是基于XMPP协议的服务器,它提供了聊天、会议、文件传输等实时通信功能。Spark...
总之,IM(Spark+Smack+Openfire)开发涉及到多个层次的技术,包括客户端开发、服务器搭建、协议处理和安全性等。通过深入学习提供的文档和支持文件,开发者可以构建出稳定、高效的即时通讯系统。
《Spark开发指导文档》 Spark,作为大数据处理领域的重要框架,以其高效、灵活和易于使用的特性,深受开发者喜爱。尤其在结合Scala编程语言时,Spark能够展现出强大的计算能力,为大规模数据处理提供了一种高性能...
本篇文章将详细探讨Spark插件开发的相关知识点,包括Spark架构、插件开发流程、常见工具以及源码解析。 首先,理解Spark的基础架构至关重要。Spark由Driver、Executor和Cluster Manager三部分组成。Driver负责任务...
Spark是一款流行的XMPP客户端,由Openfire团队开发,支持多种操作系统,包括Windows、Mac OS X和Linux。它提供了直观的用户界面,使得用户可以轻松地进行即时通讯、群聊、文件传输等功能。当ejabberd服务器设置完毕...
hive-on-spark客户端
本使用kafka,spark,hbase开发日志分析系统。 ![architecture](/docs/images/architecture.png "architecture") ### 软件模块 * Kafka:作为日志事件的消息系统,具有分布式,可分区,可冗余的消息服务功能。...
Spark连接Tigase服务器,完整的步骤,很清晰的看到。大家可以参考。