BMTD 's Yard of Fun

Technology, Sports, Music, Chinese Essays

In my last blog post (http://www.smartpeer.net/2013/10/closeable-kiosk-with-firefox-user-styles/) I used user styles to create a “closeable kiosk” with firefox. Google chrome also supports user styles so similar styles can be applied to Chrome too.

Both firefox and Chrome support another “user scripts”, which “Allows you to customize the way a web page displays or behaves, by using small bits of JavaScript.”. it can be applied to selected pages only, or to all the sites/pages. Here is a way to use user scripts to create a “closeable kiosk.”

steps for chrome:
(1) install the chrome extension “TamperMonkey” from https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo?hl=en.
(2) compose a new user script with the following code:

/ ==UserScript==
// @name       closeit
// @namespace  http://www.smartpeer.net/
// @version    0.1
// @description  close buton
// @copyright  Jie Li
// ==/UserScript==

var closeButton = document.createElement( 'img' );
closeButton.id = 'myCloseButton';
closeButton.title= 'Close the Window';
closeButton.src= 'http://gbpayment.net/hangout/close.png';
GM_addStyle(
    ' #myCloseButton {            ' +
    '    position: fixed;    ' +
    '    top: 2px; right: 8px;   ' +
    '   z-index:1000;   ' +
    ' } '
);
closeButton.addEventListener( 'click', function () {
    window.open('', '_self', '');
    window.close();
    top.close();
}, true );

document.body.appendChild( closeButton );

and click on “settings” tab on the script editor, choose “yes” for “Run only in top frame”. and then enable the script.

for firefox, it’similar, just replace TamperMonkey with the firfox addon “greaseMonkey”.

now if you open the browser in kiosk mode ( fore chrome it needs to be started from command line option “–kiosk”), there is always a big round red “X” close button at the top right corner. clicking on it will close the browser. see screen shot below:

Recently I got request to create a “closeable browser-based kiosk”– basically a browser in full screen mode, can’t be minimized/resized/moved or returned to non-full screen mode, no browser file menus, no address bar/navigation bar so user have to be stay on the same page, and can’t go to other urls. However user should be able to close it using mouse. This is to be deployed on some real kiosk booths like the ones often seen in a museum. There is no keyboard on the kiosk so short cut key combinations like alt-F4 won’t work.

Browsers like Chrome or Internet Explorer already have the built-in kiosk feature. for IE it’s the -k option; for Chrome there is the –kiosk option. if you start the browser with these options you will see the browser in kiosk mode. for firefox, there is the r-kiosk addon. Problem is that there is no way to close the browser with just a mouse once you are in kiosk mode.

One simple solution is to use firefox ‘s userscripts feature to create my own closeable kiosk mode.

the steps are:

(1) from firefox menu. option “tools”–>”options”–>”privacy”–>history, for “firefox will” dripdown, choose “use custom settings for history”, then choose the option (checkbox) “clear history when forefox closes”, then click OK button.

(2) install the “stylish” firefox extension from https://addons.mozilla.org/en-US/firefox/addon/stylish/

(3) open stylish add on, click “write new style”, an editor will open. enter the following code in the editor, then save the style and enable it.

@namespace url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);
@media not all and (-moz-windows-compositor){

.statuspanel-label {display:none !important;}
#nav-bar {display:none !important;}
#navigator-toolbox {display:none !important;}
#urlbar-container, #openLocation {display:none !important;}
#minimize-button,#restore-button,#close-button {display:none !important;}

#titlebar-max, #titlebar-min {display:none !important;}
}

now if you start firefox you will see a “closeable kiosk”. for example, “firefox https//accounts.google.com/” you will see the following “kiosk” with only the “X” close window icon on the title bar:

There are other ways to do this as well. For example, we can write some UserScripts in firefox or Chrome to inject some “close window” button onto al the web pages. so that user can always close the browser with mouse even in the native browser kiosk mode. Will give an example how that works later.

There is no enough documentation for configuration of AppFabric Event collection service. The best doc I can find is this MSDN page:
http://msdn.microsoft.com/en-us/library/hh334438

We would like to fine control when workflow tracking events are being persisted. how ever, the document does not provide details of how extactly events are schduled to be persisted to the monitor datastore. The main configurable settings are the “eventBufferSize” and “RewriteDelay” attributes in root web.xml:

<collectors>
   <collector name="" session="0">
        <settings retryCount="10" eventBufferSize="10000" retryWait="00:00:15" maxWriteDelay="00:00:05" aggregationEnabled="true" />
    </collector>
</collectors>

where the description of the attributes are:

eventBufferSize: Maximum number of events the collector buffers before writing them to the store
maxWriteDelay: If no event has arrived in this time period then events are written to the store. The collector may choose to write events even if events have arrived during this time period.

How ever, it turns out the document has a bug and “maxWriteDelay” attribute is not supported in AppFabric 1.1 version. The equivalent in AppFabric 1.1 is the “samplingInterval” attribute.

By setting these values in root web.config, we can control some of the behaviours, but still can’t guarantee when the events will be written to the store. for example, if we set the samplingInterval to 100 ( which is the minimum value allowed) and samplingInterval to 00:00:05 ( 5 seconds, the minimum interval allowed), it still takes up to 1 minute for some events to be written to the appfabric monitoring DB.

So I decided to find out what exact logic is behind this, and the way I did was to decompile the appfabric code. By using some free .net decompiler, I was able to see the source code and here is a summary of how the event collector service determine when to write to the monitoring store:

  1. The following parameters are defined in root web.xml
    • samplingInterval: minimum value 5, max 60; default 5
    • eventBufferSize: minimum value 100; max 32767;default 10000
    • maxBuffers: default5. minimum 3, max 100
  2. the value of attribute “schemaSampingInterval” is defined as part of the attribute validation paramter in the ApplicationServers_schema.xml under windows\system32\inetsrv\config\schemas, as the max value of samplingInterval, and the default value is 60.( this is the schema definitions for the attributes above:
    <attribute name="retryCount" type="int" defaultValue="5" validationType="integerRange" validationParameter="0,100" />
    <attribute name="eventBufferSize" type="int" defaultValue="10000" validationType="integerRange" validationParameter="100,32767" />
    <attribute name="maxBuffers" type="int" defaultValue="5" validationType="integerRange" validationParameter="3,100" />
    <attribute name="retryWait" type="timeSpan" defaultValue="00:00:15" validationType="timeSpanRange" validationParameter="10,120,1" />
    <attribute name="samplingInterval" type="timeSpan" defaultValue="00:00:05" validationType="timeSpanRange" validationParameter="5,60,1" />
    <attribute name="aggregationEnabled" required="false" type="bool" defaultValue="true" />

    )

  3. workflow tracking events are stored in some in-memory buffer by the event collector before they are written to monitoring store. any of the following 2 conditions trigger the data store writting ( flushing the buffer):
    • when new event is added, and buffer becomes full: events in buffer will be flushed to store. current buffer will be released into a avlaiable buffer pool. allocate a new buffer from either available buffer pool or create a new buffer if maxBuffer threadshold is not reached.
    • there is a timer job runs at interval of the value of samplingInterval seconds. and every time timer is invoked, it will flush and release the buffer if it meets all the following conditions:
      (1) there are 1 or more events in the buffer
      (2) either
      a. no new events came into the buffer since last time timer job is invoked
      or
      b. it’s more than “schemaSampingInterval” time since the buffer was flushed last time.( it’s actually tracked by comparing number of times the timer job is invoked since it ‘s last flushed to schemaSampingInterval / sampingInterval , so no exactly the value of schemaSampingInterval)

For example, if eventBufferSize is 100, samplingInterval is 00:00:05 , and the schemaSamplingInterval is the default 60, then events will be persisted to monioting store when events reaches 100 in the buffer. they will also be persisted if there are no new events between two 5 second intervals (maximum period of time of no new events coming before buffer is flushed is about 10 seconds, minimum is 5 seconds), or if the buffer has not been flushed for 60 seconds.

So depending on the speed of new events being inserted into the buffers, it can be any time between 0 and 60 seconds for an event to be flushed to the monitoring store.

This leads to a potential way of better controlling schedule of how often the events are persited– in addiotna to the values in root web.config, we can also set the values like schemaSamplingInterval to affect the scheule and from the analysis above we can calculate the relationships. for example, if we want to have the events written to monitoring store more frequently, we can set the validation range for samplingInterval to “2,2,1” in ApplicationServer_schema.xml , which means min and max value for “samplingInterval” attribute are both 2, and also set the value of samplingInterval to 00:00:02 in root web.config.

Before ending this post, I want to talk a little about another piece that we don’t want to miss. when Event Collection Service flushes the buffer and writes to MonitoringDB, it writes to a staging table in monitoring DB. on SQL server there is some SQL agent batch job that’s executed every 10 seconds ( 10 seconds is the minimum interval for any sql agent job in sql 2008) to move all records in staging table to the persistent tarcking tables in batch. If we don’t want to wait for up to 10 seocnds to see the tracking records in the persistent tables, one work around is duplicate the batch job but run at different scehdules…for example, the default job runs at seconds 10, 20, 30… of every minute, while another job runs at seconds 5, 15, 25 etc, which essentially makes the staging table job triggered every 5 seconds…

回首这几年从网络上看过的小说…

假如时间能够倒流, 假如我能够重来过 , 我也许不会浪费无数大好光阴在这上面, 从而避免了从一个愤怒青年进化成不良中年?

做梦吧傻叉.

现实总是: YY强身, 爽文V5 !

~~~~~~~~~~~~~~~~~~~~~
分界线…
~~~~~~~~~~~~~~~~~~~~~

太监的小说:

泥人的《江山如此多娇》
makelaugh的《武林旧事》
宁致远《楚氏春秋》
风月大陆
多一半《唐朝好男人》
我的超级异能
大宋时代周刊
长生

连载中或者宫中的小说:

孙晓《英雄志》
月下小羊《候补圣女》
愤怒的香蕉《赘婿》
随波逐流之神龙传奇
盛唐烟云 酒徒
妄语《凡人修仙传》
北唐
陌上行

印象最深的完本小说:

罗森的《风姿物语》。
《悟空传》今何在
墨武《江山美色》
烟雨江南《亵渎》
老猪的《紫川》
烽火戏诸侯《陈二狗的妖孽人生》
随波逐流《随波逐流之一代军师》
.凤歌《昆仑》
《沧海》
猫腻《庆余年》
月关 《回到明朝当王爷》,
大爆炸《窃明》
邪气凛然
知秋《历史的尘埃》
张恒zhtty《无限恐怖》
弹痕
狼牙三部曲
永夜
冒牌大英雄
高衙内新传
酒徒的《家园》
无语中《曲线救国》
《二鬼子汉奸李富贵》
银河英雄传说
官居一品

其他完本好书推荐:

明寐的《异人傲世录》
萧鼎的《诛仙》
当年明月《明朝的那些事儿》
锦衣夜行
枭臣
幸福像花儿一样
阿里布达年代记
阿麦从军
真心英雄 (http://www.shuku.net:8082/novels/history/csdsgz/bzdsxdzxyy.html )
太平
三生三世十里桃花
迷失在康熙末年
搜神记
间客
天王 (跳舞)
酒徒《指南录》
酒徒《明》
墨武的《纨绔才子》
沐轶《纳妾记》
极品家丁
愤怒的香蕉《隐杀》
静官《兽血沸腾》
猫腻《朱雀记》
烟雨江南《尘缘》,
大爆炸《虎狼》
月关《步步生莲》,
龙战士传奇
狼群
超级教师
恶魔法则
纨绔才子 (墨武)
大争之世 (月关)
金寻者《大唐行镖》
伯伦希尔《夜明珠》。
中国武将列传
狙击王
活色生香
杯雪
杜拉拉升职记
本无天下霸唱《鬼吹灯》
调教初唐 晴了
意乱情迷 晴了
第一次的親密接觸
超级教师II
墨武的《武林高手在校园》

传统文学:

红拂夜奔 (王小波)
血色浪漫
生命中不能承受之轻
活着
兄弟
钢铁是怎样练成的
洛丽塔

还凑合的完本:

张小花《史上第一混乱》
平凡的清穿日子
宋朝乡下人的进城生活
签约封神
张飞日记
水煮三国
大明星爱上我
卜印缜《踏歌行》
女子律师楼
太子妃升职记
老婆爱上我
花开堪折
皇后出墙记
YY之王(原名龙)
禁果
赵赶驴电梯奇遇记
花木兰之战风翔万里(田中芳树)
和空姐同居的日子
异世界女神传

烂书:

升龙道 (血红)
张三丰异界游
师士传说
租个美女当老婆

传统武侠:

黄易:
覆雨翻云
大唐双龙传
边荒传说
寻秦记
大剑师
乌金血剑

温瑞安:
血河车系列
说英雄谁是英雄系列

to encrypt a string using 3des algorithm:

echo 'somecleartext'|openssl enc -e -des3 -K 'some_key_in_hex' -iv 'some_iv_in_hex' |base64

to decrypt a 3des encrypted string:

echo 'somecipher'|base64 -d|openssl enc -d -des3 -K 'some_key_in_hex'  -iv  'some_iv_in_hex'

a bunch of symmetric encryption alorithms are supported, like AES, DES, blowfish etc:

Cipher Types
-aes-128-cbc -aes-128-cfb -aes-128-cfb1
-aes-128-cfb8 -aes-128-ecb -aes-128-ofb
-aes-192-cbc -aes-192-cfb -aes-192-cfb1
-aes-192-cfb8 -aes-192-ecb -aes-192-ofb
-aes-256-cbc -aes-256-cfb -aes-256-cfb1
-aes-256-cfb8 -aes-256-ecb -aes-256-ofb
-aes128 -aes192 -aes256
-bf -bf-cbc -bf-cfb
-bf-ecb -bf-ofb -blowfish
-camellia-128-cbc -camellia-128-cfb -camellia-128-cfb1
-camellia-128-cfb8 -camellia-128-ecb -camellia-128-ofb
-camellia-192-cbc -camellia-192-cfb -camellia-192-cfb1
-camellia-192-cfb8 -camellia-192-ecb -camellia-192-ofb
-camellia-256-cbc -camellia-256-cfb -camellia-256-cfb1
-camellia-256-cfb8 -camellia-256-ecb -camellia-256-ofb
-camellia128 -camellia192 -camellia256
-cast -cast-cbc -cast5-cbc
-cast5-cfb -cast5-ecb -cast5-ofb
-des -des-cbc -des-cfb
-des-cfb1 -des-cfb8 -des-ecb
-des-ede -des-ede-cbc -des-ede-cfb
-des-ede-ofb -des-ede3 -des-ede3-cbc
-des-ede3-cfb -des-ede3-cfb1 -des-ede3-cfb8
-des-ede3-ofb -des-ofb -des3
-desx -desx-cbc -idea
-idea-cbc -idea-cfb -idea-ecb
-idea-ofb -rc2 -rc2-40-cbc
-rc2-64-cbc -rc2-cbc -rc2-cfb
-rc2-ecb -rc2-ofb -rc4
-rc4-40 -rc5 -rc5-cbc
-rc5-cfb -rc5-ecb -rc5-ofb
-seed -seed-cbc -seed-cfb
-seed-ecb -seed-ofb