2015年10月31日星期六

P2V Windows 2000 到ESXI 5.5

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
P2V Windows 2000 到ESXI 5.5  阅读原文»

P2V Windows 2000 到ESXI 5.5

豆子需要处理掉一台旧的Windows 2000服务器,但是还有些程序和数据库在上面运行。迁移数据库以后因为某些版权的问题无法正常运行,没法子,只能整个打包P2V了。

这里有几个前提条件需要完成

1. 直接用最新版本的Vmware Converter 6是无法转换windows 2000了,因为这货实在太老了,最后一个支持的版本是Vmware Covnerter 4.0.1,而且官网上已经不能下载了。豆子在百度云上找了1个小时,终于找到一个能下载的版本。

新版本直接报错!

wKiom1Yyp0aQKUmsAAJ-l6PE0Mo558.jpg

2. Windows 2000 的版本必须是SP4 RollUP 1,不是的话先升级吧

SP4下载

http://www.microsoft.com/en-ca/download/details.aspx?id=4127

Rollup1 下载

http://www.microsoft.com/en-us/download/details.aspx?id=18997

3. 必须在执行操作的服务器上安装sysprep tool。

工具下载

http://technet.microsoft.com/en-us/library/bb742540.aspx

豆子是在一个windows 2008 R2 上操作的,那么下载解压后把 sysprep的程序拷贝到

C:\ProgramData\VMware\VMware vCenter Converter Standalone\sysprep\2k

4. 我们需要用Vmware Converter 4.01把这个windows 2000转换成一个workstation 6.5的镜像,然后再用 5.5版本把他转换都ESXi 5.5上去。

准备就绪之后,开工吧。

4.0.1版本,按部就班操作就行

wKioL1Yyp36wm1BnAAK13xPVB30080.jpg

wKiom1Yyp0mCjdT9AAJ1jVRiXWA916.jpg

wKioL1Yyp4DQgzX-AAFPhKzXMms460.jpg

wKiom1Yyp0ujJOzGAAOTAM4zlNY170.jpg

wKioL1Yyp4PjUym5AAL5NgtTdDM037.jpg

等了2个半小时,总算转换完了。然后换了台电脑,安装5.5的版本,继续转换

wKioL1Yyp4Sj49z4AAIEUj0BmdA087.jpg

wKiom1Yyp0-g-hDuAAHzhOpBISw233.jpg

wKioL1Yyp4eCNyVvAALJJoK3TgM982.jpg

wKiom1Yyp1GQiZhXAAJeqhaY7Do807.jpg

等了3个小时,成功完成,可以看见ESXi 5.5上面已经成功的转换了。

wKioL1YyqhnjjDFCAABgfoejbSI088.jpg

本文出自 "麻婆豆腐" 博客,请务必保留此出处http://beanxyz.blog.51cto.com/5570417/1707943

每日博报 精彩不止一点

Android Socket 发送广播包的那些坑  阅读原文»

Android Socket 发送广播包的那些坑

Socket广播包经常被用于局域网内的两台设备之间互相发现和消息传递,在Android应用开发过程中,也经常会遇到这样的需求,例如:两台Android设备之间、Android与手环等智能硬件之间、Android与Windows电脑之间等等。

本文主要介绍在Android中使用Socket开发广播包程序时需要注意的编程事项,以及解决方法。

首先给出一段Android发送广播包的示例代码:

  DatagramSocket socket = new DatagramSocket(8000);  socket.setBroadcast(true);  InetAddress addr = InetAddress.getByName("255.255.255.255");  byte[] buffer = "Hello World".getBytes();  DatagramPacket packet = new DatagramPacket(buffer,buffer.length);  packet.setAddress(addr);  packet.setPort(8086);  socket.send(packet);  

下面分析其中需要注意的地方:

1. 不要在主线程中发送广播包

当然,这个做Android开发的人应该都知道,不能在UI线程中执行任何网络访问相关的操作,由于广播包的发送也属于网络操作,因此必须放到单独的线程中执行。

2. 广播地址不建议使用"255.255.255.255"

上述代码中,广播包的目标地址设置为了"255.255.255.255",其实,这并不是一种推荐的做法。

"255.255.255.255" 是一种受限的广播地址,常用于在计算机不知道自己IP地址的时候发送,比如设备启动时向DHCP服务器索要地址等等,一般情况下,路由器不会转发目标为受限广播地址的广播包。

而且,有些路由器/Wi-Fi热点不支持该广播地址(例如:用Android手机做Wi-Fi热点的时候),因此在程序中会出现"ENETUNREACH (Network is unreachable)"的异常,因此,为了保证程序成功发送广播包,建议使用直接广播地址,例如:当前IP地址是 192.168.1.100,子网掩码是 255.255.255.0 的情况下,广播地址为:192.168.1.255,(具体的推算方法这里就不展开了,可以参考计算机网络相关书籍)。

那么,如何得到本网段的直接广播地址呢,下面是stackoverflow上面有位大牛分享的代码:

  public static InetAddress getBroadcastAddress(Context context) throws UnknownHostException {      WifiManager wifi = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);      DhcpInfo dhcp = wifi.getDhcpInfo();      if(dhcp==null) {          return InetAddress.getByName("255.255.255.255");      }      int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask;      byte[] quads = new byte[4];      for (int k = 0; k < 4; k++)          quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);      return InetAddress.getByAddress(quads);  }  

直接使用该函数即可得到正确的"广播地址",通过setAddress函数设置到DatagramPacket对象中即可。

3. Android设置为Wi-Fi热点时的广播地址

这是个比较大的坑,当Android设备被设置为Wi-Fi热点的时候,上面的函数得到的地址是"0.0.0.0",因此,我们需要探究当Android设备被设置为Wi-Fi热点的时候,它的IP地址究竟是多少?

有人研究了Android底层源码发现,当Android设备被设置为Wi-Fi热点的时候,其IP地址是hardcode写死在源码中的,地址是:"192.168.43.1",对应的广播地址是:"192.168.43.255"

为此,我们需要写个函数来判断一下当前Android手机是否处于Wi-Fi热点模式下,如果是,则应该使用上面给出的这个广播地址,这里给出代码示例:

  protected static Boolean isWifiApEnabled(Context context) {      try {          WifiManager manager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);          Method method = manager.getClass().getMethod("isWifiApEnabled");          return (Boolean)method.invoke(manager);      }      catch (NoSuchMethodException e) {          e.printStackTrace();      }      catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)  {          e.printStackTrace();  }      return false;  }  

Android SDK并没有开放判断是否处于热点模式的API,因此,我们需要通过反射的方式来得到,另外,注意添加权限:

  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />  

4. 小结

本文涉及到的代码被封装到了一个Broadcaster.java的文件中,可以在博文最后的附件中下载,也可以从下面的地址下载:

https://github.com/Jhuster/Android/blob/master/Socket/Broadcaster.java

关于Android Socket发送广播包的那些坑就总结到这里了,有任何疑问或者建议欢迎留言或者来信lujun.hust@gmail.com交流,或者关注我的新浪微博 @卢_俊 获取最新的文章和资讯。

本文出自 "对影成三人" 博客,请务必保留此出处http://ticktick.blog.51cto.com/823160/1707858

文章评论

发表评论

昵称:
登录快速注册
验证码:

点击图片可刷新验证码请点击后输入验证码博客过2级,无需填写验证码

内容:

同时赞一个

每日博报 精彩不止一点关闭

阅读更多内容

ASP.NET MVC过滤器 - 邹琼俊

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
ASP.NET MVC过滤器 - 邹琼俊  阅读原文»

本系列目录:ASP.NET MVC4入门到精通系列目录汇总

在ASP.NET MVC中有四种过滤器类型

App 引导界面 - 路上的脚印  阅读原文»

App 引导界面

1、前言

  最近在学习实现App的引导界面,本篇文章对设计流程及需要注意的地方做一个浅显的总结。

  附上项目链接,供和我水平类似的初学者参考——http://files.cnblogs.com/files/tgyf/Tutorial.rar

  对于有引导界面的App,刚安装或使用后将其数据清除(Setting-Apps-...),启动后就会出现引导界面,目的是向用户介绍本款应用的使用方法或主要功能。

  App引导过程的页面数一般为为3到6个,特殊的如刷机后的SetupWizard设置页面将近10个。除了非常必要,放过多页面会影响用户体验,虽然可以在界面上添加“跳过”按钮(最近较为常用的按钮为“立即体验”)为不需要被引导的用户提供进入App的捷径。

  有两种操作方式让用户左/右翻动页面:点击按钮和手势滑动。前者需要在界面上添加两个按钮(一般以左/右箭头图标作为显示内容),而后者直接识别用户手指在屏幕上的滑动操作,不过两者最终实现的页面切换方法是相同的。随着时间的推移,很多App为了界面的简洁及美观而只为用户提供手势滑动来翻动页面,当然还是有一些App仍然同时提供了上述的两种操作方式。

  先给出一张常见的引导界面图(网络上找的):

2、判断是否是第一次启动

  无论之前有没有这方面的开发经验,都不难想到:要判断App是否是第一次启动,需要从某个地方读取一个记录启动状态(或者说启动次数)的变量值,而且这个变量值不能随着应用的关闭而消失,除非将其数据清除或卸载。将这种类型的数据保存在文件中是不错的方法,但这里不用File类,因为Android提供了一个非常好用的类——SharedPreferences。

  记录启动状态的数据是在App启动后的类中进行读写的(非引导界面相关类),这里是主类MainActivity。直接上代码:

1 package com.example.tutorial;
2
3 import android.content.Context;
4 import android.content.Intent;
5 import android.content.SharedPreferences;
6 import android.content.SharedPreferences.Editor;
7 import android.os.Bundle;
8 import android.support.v7.app.ActionBarActivity;
9 import android.widget.Toast;
10
11 public class MainActivity extends ActionBarActivity {
12
13 @Override
14 protected void onCreate(Bundle savedInstanceState) {
15 super.onCreate(savedInstanceState);
16 setContentView(R.layout.activity_main);
17
18 SharedPreferences googleActivitySP = getSharedPreferences("Tutorial", Context.MODE_PRIVATE);
19 boolean firstStart = googleActivitySP.getBoolean("first_start", true);
20 if(firstStart == true){
21
22 Intent intent = new Intent(this, TutorialIntroPageActivity.class);
23 startActivity(intent);
24
25 Toast.makeText(this, "Tutorial first start", Toast.LENGTH_SHORT).show();
26 Editor edit = googleActivitySP.edit();
27 edit.putBoolean("first_start", false);
28 edit.commit();
29 }
30
31 }
32
33 }

  如代码中所示,记录App启动状态的变量为boolean型first_start,约定第一次启动时其值为true,否则为false。

  刚开始这样使用SharedPreferences类的时候,相信也有人和我一样会疑惑:如代码18、19行,一上来就是获取文件与变量值,原来不存在怎么办?这就是该类智能的地方,类似File又胜于File,当文件不存在时就创建,当变量不存在时就返回给定的默认值。即:

  a、App初次启动时会在相应目录中新建一个文件,这里是data/data/com.example.tutorial/Tutorial.xml,私有模式。注意默认是xml格式,文件名称与模式分别由方法getSharedPreferences()的第一、二参数决定。若想看其是否生成可以通过Eclipse的DDMS,若想看其内容可以通过在CMD下的adb shell命令进入Shell模式,cd定位到目录后用cat filename查看。

  b、初次启动时start_first变量并不存在,所以返回值为给定的默认值true,方法getBoolean()第一、二参数分别指定了需要获取的变量名与默认返回值,若变量存在就返回实际值,不存在就返回给定的默认值,不会因为变量不存在而报异常。不过该类还提供了判断变量是否存在的方法,感兴趣的朋友可以自己研究。

  第一次启动App,获取的start_first变量值为true,所以如代码22、23行利用Intent类打开引导界面——TutorialIntroPageActivity类实现的Activity(稍候会讲解)。接着如代码26-28行将变量值设置为false,以后运行该App获取的start_first变量值均为false,就不会打开引导界面了。

  实现过后会发现,这些曾不敢触碰以为会很高深的点也不过如此。所以,要成长就要勇于探索、犯错、总结。

3、引导界面的实现

  常见Activity的差别除了打开次数外,引导界面做的事情简单,主要是向用户展示App的使用说明与主要功能,做多加上几个按钮。

  引导界面Activity在类TutorialIntroPageActivity中进行实现,先给出代码:

  1、布局文件

2015年10月30日星期五

汤姆大叔 javascript 系列 第20课 最后的5到javascript题目 - just coding

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
汤姆大叔 javascript 系列 第20课 最后的5到javascript题目 - just coding  阅读原文»

博客链接:http://www.cnblogs.com/TomXu/archive/2012/02/10/2342098.html

原题:

大叔注:这些题目也是来自出这5个题目的人,当然如果你能答对4个及以上并且想拿高工资的话,请联系我。

  1. 找出数字数组中最大的元素(使用Match.max函数)
  2. 转化一个数字数组为function数组(每个function都弹出相应的数字)
  3. 给object数组进行排序(排序条件是每个元素对象的属性个数)
  4. 利用JavaScript打印出Fibonacci数(不使用全局变量)
  5. 实现如下语法的功能:var a = (5).plus(3).minus(6); //2
  6. 实现如下语法的功能:var a = add(2)(3)(4); //9

以前一直是写.net后台,对js的操作,只是出于dom和ajax之间,对jquery的也只是存在能使用(还不算熟练)

后来在网上找到了tom大叔的javascript系列,发现写的真好.真的是我这种dom能操作,ajax能写,jquery会用.但是希望更深入下去的采纳哦.

于是就花了一些时间来学习博客里的内容.[本文最后回附上javascript系列文章的目录列表]

现在开始答题,用我自己的思路,(因为我本身算不上一个前端,只是偶尔前端忙的时候,我就写一下dom操作,和ajax.jquery里的ajax函数都没记清,还要去查API)

所以出现纰漏和错误的地方还希望大家指出,学习.

第一题:

找出数字数组中最大的元素(使用Match.max函数).

答题思路:首先,我之前没有用过这个函数,js自带的参数提示也是一坨shit,况且弱类型语言,啥玩意都能往里面传,能不能执行就另说.

于是我就百度了一下Match.max函数,发现里面的参数是以Math.max(1,2,3,4,5,6,7) 这种模式.

去掉数组左右小括号里面的"内容"的格式就刚好满足max参数的要求.

于是:

<script type="text/javascript">
var int_array = [1,2,3,4,5,6];
var str_array ="";
for(var i = 0; i < int_array.length; i++){
str_array += int_array + ",";
}

str_array = str_array.subString(0,str_array.length-1);//这里没有找到一个string内置的去掉特定尾字符的函数(trim(),trimRight)//可能是我参数没调对

eval("Math.max("+str_array+")");


</script>

第一条还算顺利,不算太难.

第二题:转化一个数字数组为function数组(每个function都弹出相应的数字)

答题思路:将一个数字转化成function数组,并且每个函数输出对应的数字.

关键在于"弹出相对应的数字."

明显就是一个闭包的操作.(为什么说"明显",因为我花了2天时间去理解和学习闭包)....

<script type="text/javascript">
var int_array = [1,2,3,4,5,6,7];
var fn_array = [];
for(var i = 0; i < int_array.length;i++){
var f = (function(lockitem){
return function(){
console.log("当前是函数fn_"+ lockitem +" ---- 对应的数字是:" + lockitem);
}
})(int_array);

fn_array.push(f);
}


for(var j = 0 ; j < fn_array.length;j++){
console.log(fn_array[j]());
}
</script>

  

第三题:给object数组进行排序(排序条件是每个元素对象的属性个数)

答题思路:首先给一个对象的数组 比如(var obj_array = [{},{},{}]);

然后写一个函数,计算每个对象的属性个数(不包括原型属性),并返回新的对象,这个新的对象有2个属性 var newObj = {obj:obj,count:count};//Obj就是之前计算属性个数的那个对象本身,count是数量

然后在根据count属性排序,并把这个对象的obj属性返回出来.

var obj_array = [
{
name:
"张三"
},
{
name:
"张三",
age:
25
},
{
name:
"张三",
age:
25,
address:
"湖北武汉"
}
];

function propertyCount(obj){
if(typeof obj !== "object"){
throw new Error("参数类型错误!");
}
var count = 0;
for(var prop in obj){
if(obj.hasOwnProperty(prop)){
count
++;
}
}

var obj_instance = {
target:obj,
count:count
}

return obj_instance;
}

//删除数组的指定索引元素
function removeAtIndex(array,index){
array.splice(index,
1);
}


var obj_whit_propertyCount = [];
var sort_object = [];
var i_array = [];

for (var x = 0;x < obj_array.length;x++) {

obj_whit_propertyCount.push(propertyCount(obj_array[x]));
i_array.push(propertyCount(obj_array[x]).count);
i_array.sort();
}

for (var s = i_array.length - 1; s >=0;s-- ) {
sort_object.push(returnObj(s
+1));
}

console.log(obj_whit_propertyCount);
console.log(sort_object);

function returnObj(count){
for (var q = 0;q < obj_whit_propertyCount.length;q++) {
if(obj_whit_propertyCount[q].count == count){
return obj_whit_propertyCount[q].target;
}
}
}

第三体肯定不是好的思路,不过跌跌撞撞也算是做出来了.

第四题: 利用JavaScript打印出Fibonacci数(不使用全局变量)

我只做出了递归计算,对于打印出1,1,2,3,5,8....这样的数字还没思路,如果读者,请留言告诉我.

function Fibonacii(num){
if(num == 1 || num == 2){
return 1;
}

return Fibonacii(num-1) + Fibonacii(num-2);
}

console.log(Fibonacii(
5)); //第五个数

第五题:实现如下语法的功能:var a = (5).plus(3).minus(6); //2

答题思路:我一开始看到第一个(5),说是实话,真的懵了...怎么会有这么奇特的语法?只有函数调用的时候在会有f()啊!!

后来一想:(1+2)*4 ,(9/3)-1..()就很普通了,不就是一个expression么.

    然后在控制台里输出:console.log((5));//返现结果和我预期一样.

于是,就开始琢磨add和minus两个函数.

既然(5)返回就是一个number类型,那我直接就在Number的prototype属性扩展这两个方法好了.(不是老有人老生常谈不要去修改系统的原型对象)

Number.prototype.add = function(num1){
return this + a;
}

Number.prototype.minus
= function(num1){
NLog详解(三) - LayoutRender - 便当之神  阅读原文»

这期将NLog Git版本指向2005-06-09,NLog v0.9 released。这个时候的代码结构升级为这样:

和上期的版本相比,最明显的莫过于原先的Appender全套更名为Target。这期让我们来关注LayoutRender相关的实现。

LayoutRender

首先LayoutRender 继承自抽象类LayoutRenderer,并且以属性[LayoutRenderer("threadid")]的方式标注。

[LayoutRenderer("threadid")]
public class ThreadIDLayoutRenderer: LayoutRenderer

LayoutRendererFactory初始化的时候会根据该属性,加载指定程序集下面的所有LayoutRender。

public sealed class LayoutRendererFactory
{
private static TypeDictionary _targets = new TypeDictionary();

static LayoutRendererFactory()
{
Clear();
AddDefaultLayoutRenderers();
}

可以看到静态构造函数里面加载默认Renderers。

private static void AddDefaultLayoutRenderers()
{
AddLayoutRenderersFromAssembly(typeof(LayoutRendererFactory).Assembly, String.Empty);
}

public static void AddLayoutRenderersFromAssembly(Assembly theAssembly, string prefix)
{
InternalLogger.Debug("AddLayoutRenderersFromAssembly('{0}')", theAssembly.FullName);
foreach (Type t in theAssembly.GetTypes())
{
LayoutRendererAttribute[]attributes = (LayoutRendererAttribute[])t.GetCustomAttributes(typeof(LayoutRendererAttribute), false);
if (attributes != null)
{
foreach (LayoutRendererAttribute attr in attributes)
{
AddLayoutRenderer(prefix + attr.FormatString, t);
}
}
}
}

下一步就是解析配置文件中的Layout,一般包含Layout 的配置文件是这样子的:

<nlog>
<targets><target name='debug' type='Debug' layout='${basedir} ${message}' /></targets>
<rules>
<logger name='*' minlevel='Debug' appendTo='debug' />
</rules>
</nlog>

这里的layout字符串是: ${basedir} ${message},我们希望得到两个Render的数组。

这里layout.cs 里面有个关键的方法

private static LayoutRenderer[] CompileLayout(string s, out int needsStackTrace)
{
ArrayList result = new ArrayList();
needsStackTrace = 0;

int startingPos = 0;
int pos = s.IndexOf("${", startingPos);

while (pos >= 0)
{
if (pos != startingPos)
{
result.Add(new LiteralLayoutRenderer(s.Substring(startingPos, pos - startingPos)));
}
int pos2 = s.IndexOf("}", pos + 2);
if (pos2 >= 0)
{
startingPos = pos2 + 1;
string item = s.Substring(pos + 2, pos2 - pos - 2);
int paramPos = item.IndexOf(':');
string LayoutRenderer = item;
string LayoutRendererParams = null;
if (paramPos >= 0)
{
LayoutRendererParams = LayoutRenderer.Substring(paramPos + 1);
LayoutRenderer = LayoutRenderer.Substring(0, paramPos);
}

LayoutRenderer newLayoutRenderer = LayoutRendererFactory.CreateLayoutRenderer(LayoutRenderer, LayoutRendererParams);

在这个版本中,采取的是简单粗暴的截取字符串的方式。当需要的Render不存在的时候,创建的是LiteralLayoutRenderer。当存在的时候,存放在数组里返回。

LiteralLayoutRenderer本身不做什么格式化输出,只是简单的返回当前模板的值。

protected internal override int GetEstimatedBufferSize(LogEventInfo ev)
{
return _txt.Length;
}

/// <summary>
/// Renders the specified string literal and appends it to the specified <see cref="StringBuilder" />.
/// </summary>
/// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
/// <param name="ev">Logging event.</param>
protected internal override void Append(StringBuilder builder, LogEventInfo ev)
{
builder.Append(_txt);
}

最后就是Render的输出了。相比于第一思维的直接string.Replace,走了一圈Render的方式更加的安全。

StringBuilder builder = new StringBuilder(size);

for (int i = 0; i < _LayoutRenderers.Length; ++i)
{
LayoutRenderer app = _LayoutRenderers;
try
{
app.Append(builder, ev);
}
catch (Exception ex)
{
if (InternalLogger.IsWarnEnabled)
{
InternalLogger.Warn("Exception in {0}.Append(): {1}.", app.GetType().FullName, ex);
}
}
}

return builder.ToString();

这里有一个比较小的注意点,就是StringBuilder初始化的时候指定一个预估的容量size,可以较少性能损失。


本文链接:NLog详解(三) - LayoutRender,转载请注明。

阅读更多内容

2015年10月28日星期三

unity抛物线,平均速度下的运动轨迹 - 决晴谷

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
unity抛物线,平均速度下的运动轨迹 - 决晴谷  阅读原文»

之前分享了关于两点之间抛物线的“金手指”的实现方案,然后有朋友问我,一般情况下会给出速度,如何模拟自然的轨迹。

我一听这不是很容易实现么,根据之前的公式,得出两点之间时间恒定时,轨迹是确定的,也就是说平均速度是恒定。

那么反过来,在给定平均速度,然后再通过距离/速度,就可得出时间,那么轨迹也就确定了。

OK,我不多废话,直接上代码:

using UnityEngine;
using System.Collections;

public class PaoWuLine : MonoBehaviour
{
public float ShotSpeed = 10;
private float time = 1;//代表从A点出发到B经过的时长
public Transform pointA;//点A
public Transform pointB;//点B
public float g = -10;//重力加速度
// Use this for initialization
private Vector3 speed;//初速度向量
private Vector3 Gravity;//重力向量

private Vector3 currentAngle;
void Start()
{
time
= Vector3.Distance(pointA.position, pointB.position)/ShotSpeed;
transform.position
= pointA.position;//将物体置于A点
//通过一个式子计算初速度
speed = new Vector3((pointB.position.x - pointA.position.x) / time,
(pointB.position.y
- pointA.position.y) / time - 0.5f * g * time, (pointB.position.z - pointA.position.z) / time);
Gravity
= Vector3.zero;//重力初始速度为0
}
private float dTime = 0;
// Update is called once per frame
void FixedUpdate()
{

Gravity.y
= g * (dTime += Time.fixedDeltaTime);//v=at
//模拟位移
transform.position += (speed + Gravity) * Time.fixedDeltaTime;
currentAngle.x
= -Mathf.Atan((speed.y + Gravity.y) / speed.z) * Mathf.Rad2Deg;
transform.eulerAngles
= currentAngle;
}
}

这次直接把角度加上了,喜欢的朋友可以自己测试。

时间恒定的两点轨迹:http://www.cnblogs.com/jqg-aliang/p/4806017.html

一般抛物线轨迹:http://www.cnblogs.com/jqg-aliang/p/4806002.html#3292517

好了,关于愤怒的小鸟,弓箭之类的简单实现算法差不多够用了。之前我研究了很久的导弹飞行算法有了新的方向,

使用抛物线模拟动态轨迹,将会有更加真实自然的效果。欢迎关注。


本文链接:unity抛物线,平均速度下的运动轨迹,转载请注明。

uc手机浏览器使用animation的一个坑 - happycloud~~  阅读原文»

最近做一个项目,应用在移动端,其中涉及一个评论组件。按照现有的趋势,是有评论的地方必有点赞。当然我们的组件也未免于难。大概操作部分设计如下

如此简low的设计,点个赞加个一这效果实在是简直是捞比啊!!!_(:з」∠)_(我知道设计不会看到这篇文章)

怎么办,一世英名不能毁于此啊(�s�F□′)�s�喋擤ォ撸�如果加个动画会不会挽回点颜面?

卧槽,这样一个45度角仰望天空上扬的‘+1’的1s动画总算是有点潮!

狗尾续貂开干吧!衣裤!

大体方案有两种:方案一 js动态添加节点(+1),然后控制css变换。方案二 利用css3 animation实现动画。

考虑移动端css3支持度较好,性能也比用js控制的要好,果断选方案二!动画的实现很好说,keyframe定义动画就好了,这个‘+1’怎么引入呢,不想用到js。。。页面直接埋点?增加页面dom结构貌似也是不好的--、

诶~伪元素:after,:before ,定义在css里,也不会增加dom结构O(∩_∩)O~~

就这么干!~\(�R��Q)/~

先初始化好位置

&:after{
content
:(+1);
display
:block;
position
:absolute;
top
:0;
right
:5px;
font-style
: normal;
color
:rgba(255,115,0,0);
}

在定义好动画

.keyframes(~'up,0%{color:rgba(255,115,0,0);transform:translate3d(0,5px,0);}50%{color:rgba(255,115,0,1);transform:translate3d(5px,-7px,0);}100%{color:rgba(255,115,0,0);transform:translate3d(10px,-15px,0)}');

再添加上动画

&.rise:after{
.animation(up 1s linear);
}

(以上代码用了less和lesshat) 

哦了,只要点击的时候给元素添加rise这个类就好啦。测试!

chrome okay!

qq ok!

自带浏览器 ok!

uc ... uc ...uc ...尼玛你倒是飞啊!(�s�F□′)�s�喋擤ォ�

算了,uc这个坑,前面吐槽多了,应该是见怪不怪了。。。排查问题吧。

首先想到是不支持translate3d,去掉换成操作top,right依然无效,况且很多别的页面看到有用到的,难道是animation哪些属性没写全?后来参照成功动画的页面把属性补全依然不行。。。后来翻看多个页面发现都能实现animation在uc上动画的。我自己把页面copy过来也可以的!真是奇了怪了,没办法谁让在下叶良辰,我有一百个方法找出问题所在!在默默地给刚才的装逼打满分的时候想到,成功动画的页面没有一个是操作伪元素的!!!是不是这个原因呢?后来将伪元素去掉,在所有点赞的按钮下埋了<i>+1</i>这行代码。然后做动画,测试!居然ok了!!!干!!!

uc不支持伪元素使用animation动画

不能太激动,先把解决方案应用到项目上(虽然页面多了i的标签,相比js控制动态添加还是好一点,为了效果的统一折中取方案)。

哈哈哈~终于可以在自己的秘籍上写上一章《论我良辰如何打败赵日天 之 我知道uc伪元素应用css3动画bug》


本文链接:uc手机浏览器使用animation的一个坑,转载请注明。

阅读更多内容

企业日志分析之linux系统message收集展示

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
企业日志分析之linux系统message收集展示  阅读原文»

企业日志分析之linux系统message收集展示

之前写了收集linux系统历史history命令,下面介绍一下系统里日志收集与展示的。

老规矩,先看效果,满意的话继续看。

一、效果图

1、总览

wKioL1YthELSF2CGAAVVoW2EuIs388.jpg

2、linux系统日志收集数据总量

wKiom1YthEmDRT6dAACF5-7tbtg841.jpg

主要是展示所选范围内容收集日志总量

3、linux系统日志收集主机数

wKiom1YthJfy7zvhAAB1VRxXbUA808.jpg

主要是展示当前总共有多少台主机上传了message日志数据

4、linux系统日志程序类型Top5

wKioL1YthQbR556rAACUzYEf4Nw154.jpg

主要是展示收集的日志信息里前5个程序名;我这5个都是docker服务器,所以docker日志有很多。

5、linux系统日志时间数据总量图

wKioL1YthWKCJ96bAAD8n97EoUk943.jpg

主要是展示每个时间段收集的数据量

6、linux系统日志数据

wKioL1Ythe-guwNCAALjQ8a9w6c267.jpg

主要是展示详细的日志数据

安装elk的过程可以参考上一篇,地址是http://dl528888.blog.51cto.com/2382721/1703059

二、收集日志

我收集的是系统/var/log/messages日志,然后通过rsyslog的tcp 8514端口发给logstash。

1、配置rsyslog

默认rsyslog都安装了,所以只需要修改配置

在/etc/rsyslog.conf里添加

  *.* @@localhost:8514  

然后重启rsyslog

2、配置logstash

  [root@puppet tmp]# cat /etc/logstash/conf.d/logstash_agent.conf  input {      tcp {      port => "8514"      type => "syslog"     }  }  filter {    if [type] == "syslog" {      grok {        match => { "message" => "%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?: %{GREEDYDATA:syslog_message}" }      }    }  }  output {  redis {  host => ["10.10.125.8:6379"]  data_type =>"list"  key => "logstash:redis"  }  }  

3、导入模板

导入顺序

1、Linux系统日志试图.json

2、Linux系统日志搜索.json

3、Linux系统日志Dashboard.json

其他的有问题可以留言。

本文出自 "吟�D技术交流" 博客,请务必保留此出处http://dl528888.blog.51cto.com/2382721/1706204

每日博报 精彩不止一点
请输入验证码:

初窥Windows Server Container  阅读原文»

初窥Windows Server Container

相信大家对于Docker这项技术都有一定了解了,Container是一种轻量级的解决方案,非常适合将传统windows平台上的无状态服务迁移上去(相对于VM虚拟化更加能够提高整体资源利用率),加上微软的大部分技术架构都是可以整合的,而采用linux下的docker整合起来效果并不是特别好(比如我曾经尝试着用scom监控linux下Container,虽然成功了但是效果并不是很好),所以对于Windows平台的Docker我就更加期待了。今天我就把近一段时间一直零零散散做的一些小demo来做个汇总。

(图为微软Container示意图)

在开始之前,先嗦几句:

由于目前Windows Container仍处于TP3阶段(技术预览),所以存在Bug是正常的,以下是官方的原话:

Remember, this is apreviewthere are bugs and we have a lot of work in progress.This pagecontains many of our known issues.Be aware that there are some known Docker commands thatdon't workand some that onlypartially work

简单翻译下,其实就是一句话:"没有Bug才不正常呢",所以千万别在生产环境试水Windows Container(至少等到发布)

今天这个实验的目录是通过Windows Container创建一个Nginx Container(至于为什么不创建IIS Container,后面有讲述),仅作实验参考。

1、 新建Windows Server Container:


2、 输入相关配置信息后创建完成,注意我们这里先映射出8001端口作为测试端口用:


3、 创建完成后,连接到Docker Host上,使用wget -uri 'http://nginx.org/download/nginx-1.9.3.zip' -OutFile "c:\nginx-1.9.3.zip"获取源码nginx部署包,然后创建Dockerfile,new-item -Type File c:\docker\nginx\dockerfile


4、 使用Expand-Archive -Path C:\nginx-1.9.3.zip -DestinationPath C:\docker\nginx\source Force将源码解压到我们创建的目录上,待会儿dockerfile会调用到:


5、 使用notepad.exe c:\docker\nginx\dockerfile开始编写dockerfile内容:

FROM windowsservercore

LABEL Description="nginx For Windows" Vendor="nginx" Version="1.9.3"

ADD source /nginx


6、 然后使用docker build -t nginx_windows C:\docker\nginx开始使用dockerfile创建nginx images:


7、 接着我们就可以在images中看到我们刚刚创建的image:


8、我们就可以使用docker run -it --name VMC-NGC01 -p 8001:80 nginx_windows cmd调用刚刚创建的images去创建Container了,创建后如下:


9、创建完成后是直接会进入Container里面的,在Container下运行cd c:\nginx\nginx-1.9.3进入nginx主目录,并使用start nginx启动服务:


10、接着我们访问下站点页面,由于我们没有创建主页,所以访问为403(可以看到我并没有使用8001),然而我并没有找到好的方法可以修改到nginx.conf这个文件(请见Bug列表):


关于Windows Container IIS方面的尝试

1、 在不同平台的Docker上搜索IIS images:

a、Windows Container下搜索:


b、而在Linux Container下搜索IIS是这样的(虽然可能是因为Docker镜像库不同,不过就算修改了Linux上的镜像库,我认为应该不能正常在Linux Docker上进行运行):

2、不知道什么原因,部署IIS Container1总是失败的:

a、使用Images方式创建(在端口映射正确的前提下,虽然成功创建,且Container中的iis服务正常,并且还手动创建了IIS站点并开启,仍然无法访问):

b、即使是使用微软GitHub上的DockerFile+PowerShell脚本创建,仍然是有问题的(采用了最新版本的TP3 Container及10月份的最新脚本):


关于TP版目前存在的疑似Bug

1、 映射端口无法生效,比如上述例子用了8001映射Container的80端口,然而8001端口并没有生效。


2、 映射端口并不会出现在docker ps中(可以用Get-NetNatStaticMapping):


3、 进入部分docker container中运行命令经常出现卡死情况(命令无法跳到下一行),比如打开某些文本文件时:


4、 目前windows container的Container名字还是大小写敏感的(这点跟linux版无异,不知道算不算bug)

最近听了台湾的MS专家冯立伟老师关于Windows Container的课后,更加印证了我之前的想法,将来的架构极有可能是

当然一切还得等Hyper-V Container出来,让我们一起期待。

由于最近博主正在为自家公司部署VMCloud Plus版本,所以更新周期变长了,但是,只要发现新奇玩意儿,博主都会不断去实践,即使进度很慢,即使困难很多,也会坚持完成,借此来感谢各位的关注:)

职场巅峰之路(已更新)

http://mp.weixin.qq.com/s?__biz=MzAxNzIxNDA2OQ==&mid=208028889&idx=1&sn=a6cff33094b29329fd6c364272df66cc&scene=18#rd

VMCloud-OPC

阅读更多内容